学习芯片: EP4CE6F17C8
本次学习使用的为共阴极数码管,即用低电平点亮数码管,同样可知,共阳极数码管的阳极连在一起,即用高电平点亮数码管。
八段数码管示意图:
a,b,c,d,e,f,g,dg表示八段数码管时,a为最低位,dp为最高位
八段数码管用8位二进制表示,由于本次实验使用共阴极数码管,所以0表示亮,1表示灭,即数码管显示数字0我们可以用8'b1100_0000
表示,数字F使用8'b1000_0111
表示,同理可知,共阴极数码管和共阳极数码管互为对方的按位取反。
任务描述:
六个数码管同时间隔0.5s显示0-f。要求:使用一个顶层模块,调用计时器模块和数码管静态显示模块。
模块原理图:
代码设计:
veriolg
/*
2023.7.13
计时0.5s,计满输出高电平
*/
module time_count(
input wire clk ,
input wire rst_n ,
output reg flag
);
parameter MAX_NUM = 26'd24_999_999;//0.5s
reg [24:0] cnt;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt <= 26'd0;
flag <= 1'b0;
end
else if(cnt == MAX_NUM) begin
cnt <= 26'd0;
flag <= 1'b1;
end
else begin
cnt <= cnt + 1'd1;
flag <= 1'b0;
end
end
endmodule
verilog
/*
2023.7.13
数码管显示
*/
module seg_led_static(
input wire clk ,
input wire rst_n ,
input wire flag ,//计满0.5s后,输入的高电平
output reg [5:0] sel ,//位选信号
output reg [7:0] seg //段选信号
);
reg [3:0] num;//保存当前数码管显示的数字
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
sel <= 6'b111111;
end
else begin
sel <= 6'b000000;//打开全部数码管
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
num <= 4'h0;
end
else if(flag) begin
num <= num + 1'h1;
end
else begin
num <= num;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
seg <= 8'b0;
end
else begin
case(num)
4'h0: seg <= 8'b1100_0000;//匹配到后参考共阴极真值表
4'h1: seg <= 8'b1111_1001;
4'h2: seg <= 8'b1010_0100;
4'h3: seg <= 8'b1011_0000;
4'h4: seg <= 8'b1001_1001;
4'h5: seg <= 8'b1001_0010;
4'h6: seg <= 8'b1000_0010;
4'h7: seg <= 8'b1111_1000;
4'h8: seg <= 8'b1000_0000;
4'h9: seg <= 8'b1001_0000;
4'ha: seg <= 8'b1000_1000;
4'hb: seg <= 8'b1000_0011;
4'hc: seg <= 8'b1100_0110;
4'hd: seg <= 8'b1010_0001;
4'he: seg <= 8'b1000_0110;
4'hf: seg <= 8'b1000_1110;
default : seg <= 8'b1100_0000;
endcase
end
end
endmodule
verilog
/*
2023.7.13
静态数码管显示,间隔0.5s输出0------F.
*/
module top_seg_led_static(
input wire clk ,
input wire rst_n ,
output wire [5:0] sel ,
output wire [7:0] seg
);
parameter MAX_NUM = 26'd24_999_999;
wire flag_reg;
time_count #(.MAX_NUM (MAX_NUM)) u_time_count(
.clk (clk),
.rst_n (rst_n),
.flag (flag_reg)
);
seg_led_static u_seg_led_static(
. clk (clk),
. rst_n (rst_n),
. flag (flag_reg),
. sel (sel),
. seg (seg)
);
endmodule
测试文件:
verilog
`timescale 1ns/1ns
module top_seg_led_static_tb();
reg clk;
reg rst_n;
wire [5:0] sel;//位选信号
wire [7:0] seg;//段选信号
parameter MAX_NUM = 9;//切换一次状态的周期数量
parameter CYCLE = 20;//周期
always #(CYCLE/2) clk = ~clk;
initial begin
clk = 1'b0;
rst_n = 1'b0;//开始复位
#(CYCLE);
rst_n = 1'b1;//结束复位
#((MAX_NUM + 1)*CYCLE*16);
$stop;
end
top_seg_led_static #(.MAX_NUM (MAX_NUM)) u_top_seg_led_static(
.clk(clk),
.rst_n(rst_n),
.sel(sel),
.seg(seg)
);
endmodule
我们通过modelsim仿真结果如下:
运行结果: