在“夏宇闻老师之
verilog
学习站”(
http://verilog.113.tofor.com)
中
,
有这样一道题目。
设计要求如下
:
基于
CPLD
的数字钟设计
设计任务:
1
、
设计一个具有时、分、秒计时,
6
位数字显示的时钟电路;
2
、
具有快速校时功能;
3
、
具有整点音响自动报时;
4
、
以时钟电路为基础,设计如下表所示的作息时间自动打铃器;
表:自动打铃的作息时间
时间
作用
6
:
00
起床
7
:
50
上班预备
8
:
00
上班
9
:
30
工间操
12
:
00
下班
2
:
30
下午上班
5
:
30
下午下班
5
、
以时钟电路为基础设计一个工业顺序控制器,用
LED
发光管的亮与灭模拟执行机构的动作,实现要求的工艺过程。
设计要求:
1
、
按自顶向下的设计方法,画出系统实现框图。
2
、
按模块化方法进行设计,在适当的地方给出注释。
3
、
给出系统实现的完整程序或电路原理图,利用仿真手段进行功能调试,给出系统仿真波形图,下载到实验板,进行实际验证
借来练习一下:
可以看出,本题目的关键设计在一个可校正的时钟。其它均为外部设计,较为简单。故现只设计这一部分。
首先,作为数字钟的设计,即涉及到计数器:
秒表:模60计数器;
分表:模60计数器;
时表:模24计数器;
将模60计数器分成模6和模10;
将模24计数器分成模6和模4;
其次,校时功能如何实现呢?设置两个Function Key:Fm_key和Fh_key; Fm_key用来校正分表;Fh_key用来校正时表。
模块框图如下:
时钟正常运行时,分计数器以秒计数器的进位信号为clk, 时计数器以分计数器的进位信号为clk;
校时时,若Fm_key为1,则将CLK_1HZ送至分计数器作CLK,可实现分表调整;
若Fh_key为1,则将CLK_1HZ送至时计数器作CLK,可实现时表调整;
第一次编码:
/*+FHDR--------------------------------------------------------
file name: clock.v
Author:
Clarke.Lee
--------------------------------------
Clock:
1hz
Reset:
Synchronous,Low
include:
counter60.v
counter24.v
--------------------------------------
Keywords: Counter, Digital Clock
//-FHDR---------------------------------------------------------*/
`timescale 1ns/1ns
`include "counter60.v"
`include "counter24.v"
module clock(clk,
fm_key,
fh_key2,
reset,
h,
m,
s);
input clk;
input f_key1;
input f_key2;
input reset;
output [6:0] h;
output [6:0] m;
output [6:0] s;
reg [6:0] h;
reg [6:0] m;
reg [6:0] s;
wire clk_m;
wire clk_h;
wire cout_s;
wire cout_m;
wire cout_h;
counter60 counters (.clk(clk),
.reset(reset),
.cout(cout_s),
.out(s));
counter60 counterm (.clk(clkm),
.reset(reset),
.cout(cout_m),
.out(m));
counter24 counterh (.clk(clkh),
.reset(reset),
.cout(cout_h),
.out(h));
//---- clock for minute counter ------
if(fm_key)
clkm = clk;
else
clkm = cout_s;
//---- clock for hour counter --------
if(fh_key)
clkh = clk;
else
clkh = cout_m;
endmoudle
/*+FHDR--------------------------------------------------------
file name: counter60.v
Author:
Clarke.Lee
--------------------------------------
include:
counter6.v
counter10.v
--------------------------------------
Keywords: Counter
//-FHDR---------------------------------------------------------*/
`timescale 1ns/1ns
`include "counter6.v"
`include "counter10.v"
module counter60(clk,
reset,
cout,
out);
input clk;
input reset;
output cout;
output [6:0] out;
wire cout_6;
wire cout_10;
wire [2:0] out_6;
wire [3:0] out_10;
counter6 counter6 (.clk(clk),
.reset(reset),
.cout(cout_6),
.out(out_6));
counter10 counter10(.clk(cout_6),
.reset(reset),
.cout(cout),
.out(out_10));
assign out = {out_6,out_10};
endmodule
/*+FHDR--------------------------------------------------------
file name: counter24.v
Author:
Clarke.Lee
--------------------------------------
include:
counter6.v
counter4.v
--------------------------------------
Keywords: Counter
//-FHDR---------------------------------------------------------*/
`timescale 1ns/1ns
`include "counter6.v"
`include "counter4.v"
module counter24(clk,
reset,
cout,
out);
input clk;
input reset;
output cout;
output [4:0] out;
wire cout_6;
wire cout_4;
wire [2:0] out_6;
wire [1:0] out_4;
counter6 counter6 (.clk(clk),
.reset(reset),
.cout(cout_6),
.out(out_6));
counter10 counter4v(.clk(cout_6),
.reset(reset),
.cout(cout),
.out(out_4));
assign out = {out_6,out_4};
endmodule
/*+FHDR--------------------------------------------------------
file name: counter6.v
Author:
Clarke.Lee
--------------------------------------
Keywords: Counter
//-FHDR---------------------------------------------------------*/
`timescale 1ns/1ns
module counter6(clk,
reset,
cout,
out)
input clk;
input reset;
output cout;
output [2:0] out;
reg cout;
reg
[2:0] out;
reg
[2:0] counter;
always@(posedge clk)
if(!reset)
counter <= 0;
else
for(;counter++;counter<6)
out <= counter;
endmodule
/*+FHDR--------------------------------------------------------
file name: counter10.v
Author:
Clarke.Lee
--------------------------------------
Keywords: Counter
//-FHDR---------------------------------------------------------*/
`timescale 1ns/1ns
module counter6(clk,
reset,
cout,
out)
input clk;
input reset;
output cout;
output [3:0] out;
reg cout;
reg
[3:0] out;
reg
[3:0] counter;
always@(posedge clk)
if(!reset)
counter <= 0;
else
for(;counter++;counter<10)
out <= counter;
endmodule
/*+FHDR--------------------------------------------------------
file name: counter4.v
Author:
Clarke.Lee
--------------------------------------
Keywords: Counter
//-FHDR---------------------------------------------------------*/
`timescale 1ns/1ns
module counter4(clk,
reset,
cout,
out)
input clk;
input reset;
output cout;
output [1:0] out;
reg cout;
reg
[1:0] out;
reg
[1:0] counter;
always@(posedge clk)
if(!reset)
counter <= 0;
else
for(;counter++;counter<4)
out <= counter;
endmodule
编译结果:
==
ècounter6.v/counter4.v/counter10.v:
1. 红色部分
[N:0]掉了,编译通过了,功能仿真时报Pin不匹配;coding style;
2. 红色
always
块中的for语句错误,后改成:
always@(posedge clk)
if(!reset)
out <= 0;
else
for(counter=1;counter
out <= counter;
==
èclock.v:
1. 上面的红色部分出错,编译错误说明是if的判断语句必须为一个确定的值,由于Fm_key和Fh_key并没有初始化,故此处错误。后单独写了一个选择器代替。
2. 褐色部分好像不要也是可以的。但要着也不会出错。