要求:六个受到74HC595芯片控制的数码管以0.5秒为周期循环显示0到F
说明:
74HC595串行输入是从低位到高位依次输入
根据开发板的连接方式,可得输入的数据应该是 data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]};
控制模块的分频是符合芯片要求(四分频)
DS:串行输入
shcp:每一个上升沿就往移位寄存器送入一位
stcp:每一个上升沿就讲移位寄存器数据送入存储寄存器
oe:低电平时将存储寄存器中数据并行输出
module seg_595(
input wire sys_clk,
input wire sys_rst,
output wire ds,
output wire shcp,
output wire stcp,
output wire oe
);
wire [5:0] sel;
wire [7:0] seg;
shumaguan_show
#(
.cnt_max (25'd24_999_999)
)
shumaguan_show_inst
(
.sys_clk (sys_clk),
.sys_rst (sys_rst),
.sel(sel), //六个数码管
.seg(seg) //数码管段选
);
hc595_ctrl hc595_ctrl_inst(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.seg(seg),
.sel(sel),
.ds(ds), //串行输入
.shcp(shcp), //每一个上升沿就往移位寄存器送入一位
.stcp(stcp), //每一个上升沿就讲移位寄存器数据送入存储寄存器
.oe(oe) //低电平时讲存储寄存器中数据并行输出
);
endmodule
module shumaguan_show
#(
parameter cnt_max = 25'd24_999_999 //20ns的系统时钟,0.5秒的时间计数
)
(
input wire sys_clk,
input wire sys_rst,
output reg [5:0] sel, //六个数码管
output reg [7:0] seg //数码管段选
);
reg [24:0] cnt;
reg clk_flag; //标志位的使用,形成习惯(这里其实不太用的上)
reg [3:0] data; //具体显示什么
always @ (posedge sys_clk or negedge sys_rst) //时钟计数
if (!sys_rst)
cnt <= 25'd0;
else if (cnt == cnt_max)
cnt <= 25'd0;
else
cnt <= cnt + 25'd1;
always @ (posedge sys_clk or negedge sys_rst) //数据显示(十进制)用在case语句
if (!sys_rst)
data <= 4'd0;
// else if ((cnt == cnt_max) && (data == 4'd15))
else if ((clk_flag == 1'b1) && (data == 4'd15))
data <=4'd0;
else if (clk_flag == 1'b1)
data <= data +4'd1;
else
data <= data;
always @ (posedge sys_clk or negedge sys_rst) //标志位
if (!sys_rst)
clk_flag <= 1'd0;
else if (cnt == cnt_max-1'd1)
clk_flag <=1'd1;
else
clk_flag <= 1'd0;
always @ (posedge sys_clk or negedge sys_rst) //数码管位选
if (!sys_rst)
sel <= 6'b000_000;
else
sel <= 6'b111_111;
always @ (posedge sys_clk or negedge sys_rst) //数码管段选 (共阳)
if (!sys_rst)
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 hc595_ctrl(
input wire sys_clk,
input wire sys_rst,
input wire [7:0] seg,
input wire [5:0] sel,
output reg ds, //串行输入
output reg shcp, //每一个上升沿就往移位寄存器送入一位
output reg stcp, //每一个上升沿就讲移位寄存器数据送入存储寄存器
output wire oe //低电平时将存储寄存器中数据并行输出
);
wire [13:0] data; //利用组合形式给它赋值,那就得是wire型啊
assign data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]}; //将段选位选数据排列在一起方便串行输入到芯片
reg [1:0] cnt; //分频计数 74HC595对时钟有要求
reg [3:0] cnt_bit;
always @ (posedge sys_clk or negedge sys_rst)
if (!sys_rst)
cnt <= 2'd0;
else if (cnt == 2'd3)
cnt <= 2'd0;
else
cnt <= cnt +2'd1;
always @ (posedge sys_clk or negedge sys_rst) //记录串行输入到多少位了
if (!sys_rst)
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'd1;
else
cnt_bit <=cnt_bit;
always @ (posedge sys_clk or negedge sys_rst) //
if (!sys_rst)
ds <= 1'b0;
else if (cnt == 4'd0)
ds <= data[cnt_bit];
else
ds <= ds;
always @ (posedge sys_clk or negedge sys_rst) //
if (!sys_rst)
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) //
if (!sys_rst)
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