静态显示部分
使用八段数码管,具体如下图所示,这里使用共阳极数码管。
假设需要使用六位八段数码管
为了节省IO口资源这里使用74HC595芯片,具体如下所示:
MR端口有效时对数据进行清零,通常接VCC保持高电平。DS端口将串行数据传入。SHCP将穿行数据移位放入移位寄存器中,按脉冲操作。如果串行数据一次传入的数据超过8为,会将前几位多出来的数据放入Q7S端口中存入下一级595芯片,与下一个595芯片的DS端口相连接。STCP端口在上升沿时会将移位寄存器中的数据存入存储器中,当OE有效时,数据进行输出。
74HC595也可以进行级联来满足更多端口的需要,对应8个位选和6个段选14个IO口这里使用两个595芯片进行级联,如下所示:
实验目标:
从全0到全F的循环显示,每个数字显示0.5s
分模块设计
系统模块总体示意图:
module seg_static #(parameter CNT_MAX = 25'd24_999_999) ( input wire sys_clk, input wire sys_res, 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_res) if(sys_res == 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_res) //这里的flag信号作用与cnt_MAX作用重复可以不加 if(sys_res == 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; always@(posedge sys_clk or negedge sys_res) if(sys_res == 1'b0) cnt_flag <= 1'b0; else if(cnt == CNT_MAX - 1'b1) cnt_flag <= 1'b1; else cnt_flag <= 1'b0; always@(posedge sys_clk or negedge sys_res) if(sys_res == 1'b0) sel <= 6'd0; else sel <= 6'b111_111; always@(posedge sys_clk or negedge sys_res) if(sys_res == 1'b0) seg <= 8'hc0; 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_res, 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_1 ( .sys_clk(sys_clk), .sys_res(sys_res), .sel(sel), .seg(seg) ); endmodule
`timescale 1ns/1ns module tb_seg_static(); reg sys_clk; reg sys_res; wire [5:0] sel; wire [7:0] seg; initial begin sys_clk = 1'b1; sys_res <= 1'b0; #20 sys_res <= 1'b1; end always #10 sys_clk = ~sys_clk; seg_static #(.CNT_MAX(25'd24)) seg_static_1 ( .sys_clk(sys_clk), .sys_res(sys_res), .sel(sel), .seg(seg) ); endmodule
第二部分
注意拼接data数据时数码管位选信号的次序反过来,这是由于595芯片串行转并行的特性决定的,设置595需要4个时钟周期来完成一个完整数据的传输过程,利用四分频可以更好的铺垫输出四个信号的高低电平时刻
module hc595_ctr ( input wire sys_clk, input wire sys_res, 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 = {sel,seg}; always@(posedge sys_clk or negedge sys_res) if(sys_res == 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_res) if(sys_res == 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_res) if(sys_res == 1'b0) ds <= 1'b0; else if(cnt == 2'd0) ds <= data[cnt_bit]; else ds <= ds; always@(posedge sys_clk or negedge sys_res) if(sys_res == 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_res) if(sys_res == 1'b0) stcp <= 1'b0; else if((cnt == 2'd0)&&(cnt_bit == 4'b0)) stcp <= 1'b1; else if((cnt == 2'd2)&&(cnt_bit == 4'b0)) stcp <= 1'b0; else stcp <= stcp; assign oe = 1'b0; endmodule
module seg_595_static
(
input wire sys_clk,
input wire sys_res,
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_1
(
.sys_clk(sys_clk),
.sys_res(sys_res),
.sel(sel),
.seg(seg)
);
hc595_ctr hc595_ctr_1
(
.sys_clk(sys_clk),
.sys_res(sys_res),
.sel(sel),
.seg(seg),
.ds(ds),
.shcp(shcp),
.stcp(stcp),
.oe(oe)
);
endmodule
module seg_595_static
(
input wire sys_clk,
input wire sys_res,
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_1
(
.sys_clk(sys_clk),
.sys_res(sys_res),
.sel(sel),
.seg(seg)
);
hc595_ctr hc595_ctr_1
(
.sys_clk(sys_clk),
.sys_res(sys_res),
.sel(sel),
.seg(seg),
.ds(ds),
.shcp(shcp),
.stcp(stcp),
.oe(oe)
);
endmodule