74HC595:位移缓存器 seg[0]~seg[7] : sel[5]~sel[0]
第一个功能模块
module seg_static
#(
parameter CNT_MAX = 25'd24_999_999
)
(
input wire sys_clk ,
input wire sys_rst_n ,
output reg [5:0] sel ,
output reg [7:0] seg
);
reg [24:0] cnt;
reg [3:0] data;
reg cnt_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 25'd0;
else if (cnt == CNT_MAX)
cnt <= 25'd0;
else
cnt <= cnt + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
data <= 4'd0;
else if((cnt_flag == 1'b1)&&(data == 4'd15))
data <= 4'd0;
else if(cnt == CNT_MAX)
data <= data + 1'b1;
else
data <= data;
//con_flag 是为了切换字符的显示
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_flag <= 1'b0;
else if (cnt == CNT_MAX - 1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
sel <= 6'b000_000;
else
sel <= 6'b111_111;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
seg <= 8'hff;
else case(data)
4'd0: seg <= 8'hc0;
4'd1: seg <= 8'hf9;
4'd2: seg <= 8'ha4;
4'd3: seg <= 8'hb0;
4'd4: seg <= 8'h99;
4'd5: seg <= 8'h92;
4'd6: seg <= 8'h82;
4'd7: seg <= 8'hf8;
4'd8: seg <= 8'h80;
4'd9: seg <= 8'h90;
4'd10: seg <= 8'h88;
4'd11: seg <= 8'h83;
4'd12: seg <= 8'hc6;
4'd13: seg <= 8'ha1;
4'd14: seg <= 8'h86;
4'd15: seg <= 8'h8e;
default: seg <= 8'hff;
endcase
endmodule
module seg_595_static
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire ds ,
output wire shcp ,
output wire stcp ,
output wire 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 )
);
endmodule
`timescale 1ns/1ns
module tb_seg_static();
reg sys_clk;
reg sys_rst_n;
wire [5:0] sel;
wire [7:0] seg;
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
计数器计数到24清零开始下一循环计数
字符 0-f循环
字符跳变点根据flag信号变化
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 data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel};
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_bit == 4'd13)&&(cnt == 2'd3))
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'b0;
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_bit == 4'd0)&&(cnt == 2'd0))
stcp <= 1'b1;
else if ((cnt_bit == 4'd0)&&(cnt == 2'd2))
stcp <= 1'b0;
else
stcp <= stcp;
assign oe = 1'b0;
endmodule
`timescale 1ns/1ns
module tb_seg_595_static();
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
分频计数器
conf_flag
移位时钟信号 12.5MHz
stcp