今天学了数码管的不同数字的“同时”显示,以及电子时钟的实现。
今天学的新内容很少,但,进一步加深了对仿真文件的书写和理解,tcl引脚配置文件的导入。
产生的疑惑及解决:
在实现数码管的时候,不管怎么改程序,或者其他操作,将程序烧入后,什么现象都没有,就很奇怪。后来发现,原来是引脚没配置。 忘了配置是因为,我是直接赋值之前的文件夹,但忘了,我那个工程文件是新建的,所以应该重新配置。
由此也得出经验,如果烧入程序,发现啥都没显示,并且感觉程序也没问题,那就看看是不是引脚没有分配。
其他收获暂没啥,接下来是今天的代码。
计时模块
module time_count(//到达一定时间后输出一个标识符
input clk,
input rst_n,
output reg flag
);
parameter TIME = 28'd49_999_999;
reg[25:0]cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 26'd0;
flag <= 1'b1;
end
else if (cnt == TIME) begin
cnt <= 26'd0;
flag <= 1'b1;
end
else begin
cnt <= cnt + 1'd1;
flag <= 1'b0;
end
end
endmodule
时间跳变代码
module dynamic_set(
input clk,
input rst_n,
input flag,
input flag_s,
output reg[5:0] sel,
output reg[7:0] seg
);
reg [3:0] cstate;//当前 状态
reg [3:0] nstate;//下一个 状态
reg [2:0]value;
reg [16:0]sec_sum;//记录过去总秒数
wire [1:0] hour_h;
wire [3:0] hour_l;
wire [2:0] min_h;
wire [3:0] min_l;
wire [2:0] sec_h;
wire [3:0] sec_l;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cstate <= 3'd0;
end
else begin
cstate <= nstate;
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
sec_sum<= 17'd30000;
end
else if(sec_sum == 17'd86399)begin
sec_sum <=17'd0;
end
else if(flag_s) begin
sec_sum <= sec_sum + 1'd1;
end
else begin
sec_sum <= sec_sum;
end
end
assign hour_h = sec_sum / 3600/10;
assign hour_l = sec_sum /3600 %10;
assign min_h = sec_sum %3600 / 60 / 10;
assign min_l = sec_sum %3600 / 60 % 10;
assign sec_h = sec_sum %60 /10;
assign sec_l = sec_sum %60 %10;
reg [9:0]time_state;
//时间显示内容的切换表
// always @(*)begin
// if(!rst_n)begin
// time_state = 4'd0;
// end
// else begin
// case (time_state)
// 4'd0: begin
// if (flag_s) begin
// time_state = 4'd1;
// end
// else begin
// time_state = 4'd0;
// end
// end
// 4'd1: begin
// if (flag_s) begin
// time_state = 4'd2;
// end
// else begin
// time_state = 4'd1;
// end
// end
// 4'd2: begin
// if (flag_s) begin
// time_state = 4'd3;
// end
// else begin
// time_state = 4'd2;
// end
// end
// 4'd3: begin
// if (flag_s) begin
// time_state = 4'd4;
// end
// else begin
// time_state = 4'd3;
// end
// end
// 4'd4: begin
// if (flag_s) begin
// time_state = 4'd5;
// end
// else begin
// time_state = 4'd4;
// end
// end
// 4'd5: begin
// if (flag_s) begin
// time_state = 4'd6;
// end
// else begin
// time_state = 4'd5;
// end
// end
// 4'd6: begin
// if (flag_s) begin
// time_state = 4'd7;
// end
// else begin
// time_state = 4'd6;
// end
// end
// 4'd7: begin
// if (flag_s) begin
// time_state = 4'd8;
// end
// else begin
// time_state = 4'd7;
// end
// end
// 4'd8: begin
// if (flag_s) begin
// time_state = 4'd9;
// end
// else begin
// time_state = 4'd8;
// end
// end
// 4'd9: begin
// if (flag_s) begin
// time_state = 4'd0;
// end
// else begin
// time_state = 4'd9;
// end
// end
// default: ;
// endcase
// end
// end
//位选状态切换
always @(*)begin
if(!rst_n)begin
nstate = 3'd0;
end
else begin
case (cstate)
3'd0: if (flag) begin
nstate = 3'd1;
end
else begin
nstate =3'd0;
end
3'd1: if (flag) begin
nstate = 3'd2;
end
else begin
nstate =3'd1;
end
3'd2: if (flag) begin
nstate = 3'd3;
end
else begin
nstate =3'd2;
end
3'd3: if (flag) begin
nstate = 3'd4;
end
else begin
nstate =3'd3;
end
3'd4: if (flag) begin
nstate = 3'd5;
end
else begin
nstate =3'd4;
end
3'd5: if (flag) begin
nstate = 3'd6;
end
else begin
nstate =3'd5;
end
3'd6: if (flag) begin
nstate = 3'd0;
end
else begin
nstate =3'd6;
end
default: nstate = 3'd0;
endcase
end
end
//最后的位显示
always @(*)begin
if(!rst_n)begin
sel = 6'd0;
end
else begin
case (cstate)//cstate 位选,time_state显示内容选择
3'd0: begin
sel = 6'b111_110;
value = hour_h;
end
3'd1: begin
sel = 6'b111_101;
value = hour_l;
end
3'd2: begin
sel = 6'b111_011;
value = min_h;
end
3'd3: begin
sel = 6'b110_111;
value = min_l;
end
3'd4: begin
sel = 6'b101_111;
value = sec_h;
end
3'd5: begin
sel = 6'b011_111;
value = sec_l;
end
default: sel = 6'b000_000 ;
endcase
end
end
always @(*)begin
if(!rst_n)begin
seg = 8'd0;
end
else begin
case (value)
4'd0: seg <= 8'b1100_0000;//匹配到后参考共阳极真值表
4'd1: seg <= 8'b1111_1001;
4'd2: seg <= 8'b1010_0100;
4'd3: seg <= 8'b1011_0000;
4'd4: seg <= 8'b1001_1001;
4'd5: seg <= 8'b1001_0010;
4'd6: seg <= 8'b1000_0010;
4'd7: seg <= 8'b1111_1000;
4'd8: seg <= 8'b1000_0000;
4'd9: seg <= 8'b1001_0000;
endcase
end
end
endmodule
顶层文件
module top_sel_dynamic(
input clk,
input rst_n,
output [5:0] sel,
output [7:0] seg
);
parameter TIME = 26'd99_999;
wire flag_reg;
wire flag_s;
time_count #(.TIME(TIME)) u_time_count(
.clk(clk),
.rst_n(rst_n),
.flag(flag_reg)
);
time_count #(.TIME((TIME+1)*500)) u_time_s(
.clk(clk),
.rst_n(rst_n),
.flag(flag_s)
);
dynamic_set u_sel_dynamic(//数码管控制模块
.clk(clk),
.rst_n(rst_n),
.flag_s(flag_s),
.flag(flag_reg),
.sel(sel),
.seg(seg)
);
endmodule
静态显示:
数码管设置代码
module dynamic_set(
input clk,
input rst_n,
input flag,
output reg[5:0] sel,
output reg[7:0] seg
);
reg [3:0] cstate;//当前 状态
reg [3:0] nstate;//下一个 状态
reg [2:0]value;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cstate <= 3'd0;
end
else begin
cstate <= nstate;
end
end
always @(*)begin
if(!rst_n)begin
nstate = 3'd0;
end
else begin
case (cstate)
3'd0: if (flag) begin
nstate = 3'd1;
end
else begin
nstate =3'd0;
end
3'd1: if (flag) begin
nstate = 3'd2;
end
else begin
nstate =3'd1;
end
3'd2: if (flag) begin
nstate = 3'd3;
end
else begin
nstate =3'd2;
end
3'd3: if (flag) begin
nstate = 3'd4;
end
else begin
nstate =3'd3;
end
3'd4: if (flag) begin
nstate = 3'd5;
end
else begin
nstate =3'd4;
end
3'd5: if (flag) begin
nstate = 3'd6;
end
else begin
nstate =3'd5;
end
3'd6: if (flag) begin
nstate = 3'd0;
end
else begin
nstate =3'd6;
end
default: nstate = 3'd0;
endcase
end
end
always @(*)begin
if(!rst_n)begin
sel = 6'd0;
end
else begin
case (cstate)
3'd0: begin
sel = 6'b111_110;
value = 3'd1;
end
3'd2: begin
sel = 6'b111_101;
value = 3'd2;
end
3'd3: begin
sel = 6'b111_011;
value = 3'd3;
end
3'd4: begin
sel = 6'b110_111;
value = 3'd4;
end
3'd5: begin
sel = 6'b101_111;
value = 3'd5;
end
3'd6: begin
sel = 6'b011_111;
value = 3'd6;
end
default: sel = 6'b000_000 ;
endcase
end
end
always @(*)begin
if(!rst_n)begin
seg = 8'd0;
end
else begin
case (value)
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;
endcase
end
end
endmodule
顶层文件代码
module top_sel_dynamic(
input clk,
input rst_n,
output [5:0] sel,
output [7:0] seg
);
parameter TIME = 26'd99_999;
wire flag_reg;
wire flag_s;
time_count #(.TIME(TIME)) u_time_count(
.clk(clk),
.rst_n(rst_n),
.flag(flag_reg)
);
time_count #(.TIME((TIME+1)*500)) u_time_s(
.clk(clk),
.rst_n(rst_n),
.flag(flag_s)
);
dynamic_set u_sel_dynamic(//数码管控制模块
.clk(clk),
.rst_n(rst_n),
.flag_s(flag_s),
.flag(flag_reg),
.sel(sel),
.seg(seg)
);
endmodule