You are on page 1of 4

《数字逻辑与数字系统》实验报告 天津大学本科生实验报告专用纸

学院 智能学部 年级 2017 级 班级五 班 姓名罗多福 学号 6317000036 三.实验原理与步骤(注:步骤不用写工具的操作步骤,而是设计步骤)

课程名称 实验日期 成绩

同组实验者

实验项目名称 数字逻辑实验 3

1. 实验目的
1. 1. 掌握基于 SystemVerilog HDL 的时序逻辑电路建模方法;
2. 掌握计数器设计方法,并能够使用计数器设计使能时钟(用于时钟分频);
3. 掌握移位寄存器设计方法,并能够利用移位寄存器设计边沿检测电路;
4. 掌握 7 段数码管的动态显示。 1. 首先实现边沿检测电路,命名为 chk_asc 模块。阅读实验指导书可知,i_start 可
看作一个按钮,每按一次改变一次当前电路的状态。所以 chk_asc 模块中需要使
用到 2 位移位寄存器,来存储两个状态,可看作现态和次态。
代码:

`timescale 1ns / 1ps

module chk_asc(
input sys_clk,
2. 实验内容 input sys_rst_n,
input cin,
基于 SystemVerilog HDL 设计并实现一个分秒数字钟。整个工程的顶层模块 如图 3-6 所示,输入/输出 output logic cout
端口如表 3-1 所示。使用 4 个七段数码管显示当前的 计时。其中,两个数码管对应“分”,另两个数码 );
管对应“秒”。通过 1 个拨动开关 对数字钟进行复位控制。使用 1 个按键对数字中进行“暂停/计时”
控制,按键每按 下一次,进行暂停和计时的切换,即暂停时,按下按键启动计时;计时过程中, 按下按 logic [1:0]temp=0;
键暂停计时 logic en=0;
always_ff @(posedge sys_clk) begin
if(sys_rst_n==1) begin
temp={cin,temp[1]};
if(temp[1]==1&&temp[0]==0) en=~en;
end
else begin
temp=0;
en=0;
end
end
assign cout=(en==1?1:0);
endmodule
2.然后实现使能时钟生成器,命名为 en_clock 模块。其中时钟周期为 40ns,而七段数码管动态扫描周期为

1ms,所以可以得出每经过 25000 个时钟周期,七段数码管会进行一次扫描。建模时可以使用一个计数器来实


现这个功能。同时,分秒数字时钟一共需要 4 个七段数码管,所以输出 an 应该有 4 个状态

代码:
3.之后实现计时电路,命名为 cnt_clock 模块。分秒时钟每加 1 秒需要经过 2 千 500
`timescale 1ns / 1ps 万 40ns 的时钟周期。与使能时钟生成器类似,可以使用计数器实现此功能
代码:
module en_clock( `timescale 1ns / 1ps
input sys_clk,
input sys_rst_n, module cnt_clock(
output logic [3:0]cout input sys_clk,
); input sys_rst_n,
input en,
integer r_cnt=0; output logic [7:0]min,
always_ff @(posedge sys_clk) begin output logic [7:0]sec
if(sys_rst_n==1) begin );
if(r_cnt==24999) begin
if(cout==4'b0000) cout=4'b0001; integer cnt=0;
else if(cout==4'b0001) cout=4'b0010; integer CNT=0;
else if(cout==4'b0010) cout=4'b0100; always_ff @(posedge sys_clk) begin
else if(cout==4'b0100) cout=4'b1000; if(sys_rst_n==1) begin
else if(cout==4'b1000) cout=4'b0001; if(en==1) begin
r_cnt=0; if(cnt==24999) begin
end cnt=0;
else begin CNT=CNT+1;
r_cnt=r_cnt+1; if(CNT==999) begin
end CNT=0;
end sec=sec+1;
else begin if(sec==60) begin
r_cnt=0; min=min+1;
cout=4'b0; sec=0;
end end
end end
end
endmodule else begin
cnt=cnt+1;
end
end
end
else begin
cnt=0;
CNT=0;
3. 还需要写一个 BCD 码转换为七段数码管信号的模块,命名为 BCD_2_7Dig 模块。
min=0;
sec=0;
使用 case 语句即可完成
end
end
代码:
`timescale 1ns / 1ps endmodule

module BCD_2_7Dig( 5.完成以上 4 个模块后,可以在 dig_clock 中进行实例化了


input [3:0] BCD,
output logic [7:0] a_to_g • 1 个 cn_clock 模块:每个 7 段数码管扫描周期提供一个使能信号,即输出
); an,判断当前需要控制哪一个 7 段数码管;

always @(*) begin • 1 个 chk_asc 模块:通过 i_start 判断当前时钟的状态;


case (BCD)
// gfedcba • 1 个 cnt_clock 模块:当使能端有效时,进行计时;
4'b0000:a_to_g=8'b11000000;
4'b0001:a_to_g=8'b11111001; • 2 个 bin2bcd_0 模块(由老师提供):将 cnt_clock 模块得到的分和秒的二进
4'b0010:a_to_g=8'b10100100; 制数转换为 BCD 码;
4'b0011:a_to_g=8'b10110000;
4'b0100:a_to_g=8'b10011001; • 4 个 BCD_2_7Dig 模块:将所得到的 BCD 码分成四部分再转换为 7 段数
4'b0101:a_to_g=8'b10010010; 码管的信号;
4'b0110:a_to_g=8'b10000010;
4'b0111:a_to_g=8'b11011000; 此外,由于每次输出 a_to_g 只能控制一个 7 段数码管(即实验报告中所提到的,
4'b1000:a_to_g=8'b10000000; 4 个 7 段数码管并不是同时亮或灭,是有规律地高频的切换),所以要根据 cn_clock
4'b1001:a_to_g=8'b10010000; 模块得到的使能信号,给 a_to_g 赋值。
default: a_to_g=8'b11111111; 代码:
endcase
// 8'b11111111:nothing `timescale 1ns / 1ps
// 8'b01111111:P(dot)
// 8'b10111111:G module dig_clock(
// 8'b11011111:F input sys_clk,
// ? input sys_rst_n,
// 8'b11101111:E input i_start,
// 8'b11110111:D output logic [3 : 0] an,
// 8'b11111011:C output logic [7 : 0] a_to_g
// 8'b11111101:B );
// 8'b11111110:A
// ? // 输出七段数码管的使能端
end logic [3:0] en;
en_clock en_clk(sys_clk,sys_rst_n,en);
endmodule assign an=en;
// 输出计时器状态,开始/暂停
logic i_start_en;
chk_asc chkasc(sys_clk,sys_rst_n,i_start,i_start_en);
// 输出计时器的时间,分+秒
logic [7:0]min;
logic [7:0]sec;
cnt_clock cnt_clk(sys_clk,sys_rst_n,i_start_en,min,sec);
// Binary to BCD
logic [7:0]minBCD;
logic [7:0]secBCD;
bin2bcd_0 minute(min,minBCD);
bin2bcd_0 second(sec,secBCD);
// BCD to a_to_g
logic [7:0] a_to_g_min_01;
BCD_2_7Dig min_01(minBCD[3:0],a_to_g_min_01);
logic [7:0] a_to_g_min_10;
BCD_2_7Dig min_10(minBCD[7:4],a_to_g_min_10);
logic [7:0] a_to_g_sec_01;
BCD_2_7Dig sec_01(secBCD[3:0],a_to_g_sec_01);
logic [7:0] a_to_g_sec_10;
BCD_2_7Dig sec_10(secBCD[7:4],a_to_g_sec_10);
integer r_cnt=0;
always @(*) begin
a_to_g=8'b11111111;
if(i_start_en==1) begin
if(en==4'b0000) a_to_g=8'b11111111;
else if(en==4'b0001) a_to_g=a_to_g_sec_01;
else if(en==4'b0010) a_to_g=a_to_g_sec_10;
else if(en==4'b0100) begin
a_to_g=a_to_g_min_01;
a_to_g[7]=0;
实验问题 end
分秒数字钟电路中一共使用了几个计数器,作用分别是什么? else if(en==4'b1000) a_to_g=a_to_g_min_10;
end
答:2 个。 end

第一个用来将时钟频率分频为 7 段数码管扫描的频率; endmodule

第二个用来将时钟频率分频为 1Hz,实现计时功能,每秒+1
教师签字:

年 月 日

You might also like