一.任务描述
- 本实验旨在实现六个数码管实现流水显示1-6,右边第一位显示1;1s后第一位灭,右边第二位显示2。以此类推,以实现动态数码管
二.模块图
三.设计思路
-
状态转移图
-
1.flag状态转移条件:计满1s
2.考察状态:确定对应的sel应该哪个亮;并data赋给对应的值
3.考察data:data值对应真值表给seg赋值
四.代码
- time_count
/**************************************功能介绍***********************************
Date : 2023年7月29日17:14:59
Author : Alegg xy.
Version : 1.0
Description: 计时1s模块
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module time_count(
input clk ,
input rst_n ,
output reg flag //计满1s标志
);
//---------<参数定义>---------------------------------------------------------
parameter MAX_TIME = 26'd50_000_000;
//---------<内部信号定义>-----------------------------------------------------
reg [25:0] cnt ;
wire add_cnt ;
wire end_cnt ;
//1s计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 25'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 25'd0;
end
else begin
cnt <= cnt + 1'b1;
end
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == MAX_TIME - 1'd1;
//flag信号定义,1为计满
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
flag <= 1'b0;
end
else if(end_cnt)begin
flag <= 1'b1;
end
else begin
flag <= 1'b0;
end
end
endmodule
- dynamic_seg
/**************************************功能介绍***********************************
Date :2023年7月29日17:15:43
Author : Alegg xy.
Version : 1.0
Description: 实现动态数码管
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module dynamic_seg(
input clk ,
input rst_n ,
input flag ,
output reg [5:0] sel ,
output reg [7:0] seg
);
//---------<参数定义>---------------------------------------------------------
//---------<内部信号定义>-----------------------------------------------------
//状态空间
localparam S0 = 'd0,//右起第一位
S1 = 'd1,//右起第二位
S2 = 'd2,//右起第三位
S3 = 'd3,//左起第三位
S4 = 'd4,//左起第二位
S5 = 'd5;//左起第一位
reg [2:0] cstate ;//现态
reg [2:0] nstate ;//次态
//第一段:时序逻辑描述状态转移
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cstate <= S0;
end
else begin
cstate <= nstate;
end
end
//第二段:组合逻辑描述状态转移规律和状态转移条件
always @(*) begin
case(cstate)
S0 : begin
if (flag) begin
nstate = S1;
end
else begin
nstate = cstate;
end
end
S1 : begin
if (flag) begin
nstate = S2;
end
else begin
nstate = cstate;
end
end
S2 : begin
if (flag) begin
nstate = S3;
end
else begin
nstate = cstate;
end
end
S3 : begin
if (flag) begin
nstate = S4;
end
else begin
nstate = cstate;
end
end
S4 : begin
if (flag) begin
nstate = S5;
end
else begin
nstate = cstate;
end
end
S5 : begin
if (flag) begin
nstate = S0;
end
else begin
nstate = cstate;
end
end
default : nstate = cstate;
endcase
end
reg [2:0] data;
//第三段:描述输出,时序逻辑或组合逻辑皆可
always @(*)begin
if(!rst_n)begin
data = 3'd0;
end
else begin
case (cstate)
S0:begin
sel = 6'b011_111;
data = 3'd1;
end
S1:begin
sel = 6'b101_111;
data = 3'd2;
end
S2:begin
sel = 6'b110_111;
data = 3'd3;
end
S3:begin
sel = 6'b111_011;
data = 3'd4;
end
S4:begin
sel = 6'b111_101;
data = 3'd5;
end
S5:begin
sel = 6'b111_110;
data = 3'd6;
end
default: begin
sel = 6'b111_111;
data = 3'd0;
end
endcase
end
end
always @(*)begin
if(!rst_n)begin
seg = 8'b1111_1111;
end
else begin
case (data)
3'd1:seg = 8'b11111001;
3'd2:seg = 8'b10100100;
3'd3:seg = 8'b10110000;
3'd4:seg = 8'b10011001;
3'd5:seg = 8'b10010010;
3'd6:seg = 8'b10000010;
default: seg = 8'b0000_0000;
endcase
end
end
endmodule
- top_dynamic_seg
/**************************************功能介绍***********************************
Date : 2023年7月29日17:38:19
Author : Alegg xy.
Version : 1.0
Description: 动态数码管顶层模块
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module top_dynamic_seg(
input clk ,
input rst_n ,
output [5:0] sel ,
output [7:0] seg
);
//---------<参数定义>---------------------------------------------------------
parameter MAX_TIME = 26'd50_000_000;
//---------<内部信号定义>-----------------------------------------------------
wire flag_link;
time_count #(.MAX_TIME(MAX_TIME)) u_time_count(
.clk (clk),
.rst_n (rst_n),
.flag (flag_link)
);
dynamic_seg u_dynamic_seg(
.clk (clk),
.rst_n (rst_n),
.flag (flag_link),
.sel (sel),
.seg (seg)
);
endmodule
五.仿真
- 仿真文件
`timescale 1ns/1ns
module tb_dynamic_seg();
//激励信号定义
reg tb_clk ;
reg tb_rst_n ;
//输出信号定义
wire [5:0] tb_sel ;
wire [7:0] tb_seg ;
//时钟周期参数定义
parameter CLOCK_CYCLE = 20;
defparam u_top_dynamic_seg.MAX_TIME = 10;
//模块例化
top_dynamic_seg u_top_dynamic_seg(
.clk (tb_clk ),
.rst_n (tb_rst_n ),
.sel (tb_sel ),
.seg (tb_seg )
);
//产生时钟
initial tb_clk = 1'b0;
always #(CLOCK_CYCLE/2) tb_clk = ~tb_clk;
//产生激励
initial begin
tb_rst_n = 1'b1;
#(CLOCK_CYCLE*2);
tb_rst_n = 1'b0;
#(CLOCK_CYCLE*20);
tb_rst_n = 1'b1;
#(10*CLOCK_CYCLE*6)
$stop;
end
endmodule
- 仿真效果