input clk,sh,sm,ss,start,md,rst
wire clks,clks0,clkm0,clkh0
reg clkm,clkh
reg[7:0] h,m,s
output[6:0] h1,h0,s0,s1,m1,m0
output reg bo
initial begin h=0m=1s=0end //陪册初始化定时器 \
fp m21(.clk_in(clk),.clk_out(clks))//分频模块
assign clks0=clks&&start||!ss||!rst//百分秒计时块
always@(posedge clks0 )
if(!rst) s<=0
else if(md) begin s<=s+1if(s==99)s<=0end
else if((h==0)&&(m==0)&&(s==0)) s<=0
else if(s==0) begin
s<=99clkm<=1end
else begin s<=s-1clkm<=0end
assign clkm0=clkm||!sm||!rst//秒计时块
always@(posedge clkm0 )
if(!rst) m<=0
else if(md)begin m<=m+1if(m==59)m<=0end
else if(m==0) begin m<=59clkh<=1end
else begin m<=m-1clkh<=0end
assign clkh0=clkh||!sh||!rst//早衡分计时块
always@(posedge clkh0 )
if(!rst) h<=0
else if(md)begin h<=h+1if(h==60)h<=0end
else if (h==0) h<=60
else h<=h-1
always@(h,s,m ) //定时终点报时块
if(h==0&&m==0&&s==0) begin bo=1end
else bo=0
m10led
m20(.h(h),.m(m),.s(s),.h1(h1),.h0(h0),.m1(m1),.m0(m0),.s0(s0),.s1(s1))//数码管显示块
endmodule
module fp(clk_in,clk_out)//将27MHz分频为1Hz
input clk_in
output reg clk_out
reg [31:0] q
initial q=0
always@(posedge clk_in)
if(q==13500000) begin clk_out<=1q<=q+1end
else if(q==27000000) begin clk_out<=0q<=0end
else q<=q+1
endmodule
module m10led(h,m,s,h1,h0,m1,m0,s0,s1)//时分秒的个位十位分离成两组十六进制数
input[7:0] h,m,s
wire [6:0] a0,a1,b0,b1,c0,c1
output[7:0] h1,h0,s0,s1,m1,m0
wire[7:0] seg0,seg1,seg2
assign a0=s%10,a1=s/10
assign {seg0[7:4],seg0[3:0]}={a1[3:0],a0[3:0]}//分离分
led m00(.SW(seg0),.HEX1(s1),.HEX0(s0))//调用子模块led
assign b0=m%10,b1=m/10
assign {seg1[7:4],seg1[3:0]}={b1[3:0],b0[3:0]}
led m01(.SW(seg1),.HEX1(m1),.HEX0(m0))//调用子模块led
assign c0=h%10,c1=h/10/陆乱做/分离时
assign {seg2[7:4],seg2[3:0]}={c1[3:0],c0[3:0]}
led m10(.SW(seg2),.HEX1(h1),.HEX0(h0))//调用子模块led
endmodule
module led(SW,HEX1,HEX0)//将两组十六进制数转码为数码管显示的数值
input [7:0]SW
output reg[6:0]HEX1,HEX0
parameter seg0= 7'b1000000,
seg1 = 7'b1111001,
seg2 = 7'b0100100,
seg3 = 7'b0110000,
seg4= 7'b0011001,
seg5 = 7'b0010010,
seg6 = 7'b0000010,
seg7 = 7'b1111000,
seg8 = 7'b0000000,
seg9 = 7'b0010000,
sega = 7'b0001000,
segb = 7'b0000011,
segc = 7'b1000110,
segd = 7'b0100001,
sege = 7'b0000110,
segf = 7'b0001110
always @(*)
case(SW[3:0]) //第一组十六进制转换
4'h0: HEX0[6:0] = seg0
4'h1: HEX0[6:0] = seg1
4'h2: HEX0[6:0] = seg2
4'h3: HEX0[6:0] = seg3
4'h4: HEX0[6:0] = seg4
4'h5: HEX0[6:0] = seg5
4'h6: HEX0[6:0] = seg6
4'h7: HEX0[6:0] = seg7
4'h8: HEX0[6:0] = seg8
4'h9: HEX0[6:0] = seg9
4'ha: HEX0[6:0] = sega
4'hb: HEX0[6:0] = segb
4'hc: HEX0[6:0] = segc
4'hd: HEX0[6:0] = segd
4'he: HEX0[6:0] = sege
4'hf: HEX0[6:0] = segf
default:HEX0[6:0] = seg0
endcase
always @(*)
case(SW[7:4])//第一组十六进制转换
4'h0: HEX1[6:0] = seg0
4'h1: HEX1[6:0] = seg1
4'h2: HEX1[6:0] = seg2
4'h3: HEX1[6:0] = seg3
4'h4: HEX1[6:0] = seg4
4'h5: HEX1[6:0] = seg5
4'h6: HEX1[6:0] = seg6
4'h7: HEX1[6:0] = seg7
4'h8: HEX1[6:0] = seg8
4'h9: HEX1[6:0] = seg9
4'ha: HEX1[6:0] = sega
4'hb: HEX1[6:0] = segb
4'hc: HEX1[6:0] = segc
4'hd: HEX1[6:0] = segd
4'he: HEX1[6:0] = sege
4'hf: HEX1[6:0] = segf
default:HEX1[6:0] = seg0
endcase
endmodule
module Timer_Design(input wire clk, //时钟信号输入端F = 1Hz P = 1s
input wire res, //复位信号,Low Active低有效
input wire [1:0] data, //定时模式[长短]选择
output reg x
)
/*******************************功能描述***************************
data = 2'b00 -> 无定时, 告警信号X一直为0
data = 2'b01 -> 5s定时, 告警信号X保持6s的高,但是5s就会输出一个
告警,这个有一点冲突
data = 2'b10 -> 10s定时,每隔10s输出一个告警信号,告警信号保持6s
data = 2'b11 -> 15s定时,每隔15输出一个告警有效信号
******************************************************************/
//这里有一个不明确的地方,是否定时是一直在运行,如果一直在运行定时,那么第一个假设定时时间是5s
//5s到了之后告警信号拉高,此时定时清零继续运行,告警信号要保持6s的高,那么5s定时到的时候告警信
//号依旧是高,以此循环,5S定时的话X会一直保持高。
//另外一种情罩世况是定时一直在运行,但困闷游是X持续高时间需要低于定时周期5s
//第三种可能是定时不一直运行,定时到5s之后,X输出6s的高,此时定时是停止的,6s之后重新开始定时
//但是这个定时周期的定义就有问题了
//所以考虑以上情况,我选择第二种,将X持续时间缩短到3s
reg [3:0] timer_cnt
always @(posedge clk,negedge res) begin
if(!rss) begin
x <= 1'b0
timer_cnt <= 4'd0
end
else case(data)
2'b00 : begin
x <= 1'b0
timer_cnt <= 4'd0
end
2'b01 : begin //定时5s
if(timer_cnt <= 4'd1) begin
x <= x //刚开始定时的时候不能将之拉高,所以这里用保持
timer_cnt <= timer_cnt + 1'b1
end
else if(timer_cnt <= 4'd3) begin
timer_cnt <= timer_cnt + 1'b1
x <= 1'b0
end
else begin //timer_cnt = 4
timer_cnt <= 4'd0
x <= 1'b1
end
end
2'b10 : begin //定时10
if(timer_cnt <= 4'd1) begin //x保持3s的高
x <= x //刚开始定时的时候不能将之拉高,所以这里用保持
timer_cnt <= timer_cnt + 1'b1
end
else if(timer_cnt <= 4'd8) begin
timer_cnt <= 汪销timer_cnt + 1'b1
x <= 1'b0
end
else begin //timer_cnt = 9
timer_cnt <= 4'd0
x <= 1'b1
end
end
2'b11 : begin //定时15
if(timer_cnt <= 4'd1) begin //x保持3s的高
x <= x //刚开始定时的时候不能将之拉高,所以这里用保持
timer_cnt <= timer_cnt + 1'b1
end
else if(timer_cnt <= 4'd13) begin //cnt = 2~(14-1)
timer_cnt <= timer_cnt + 1'b1
x <= 1'b0
end
else begin //timer_cnt = 14
timer_cnt <= 4'd0
x <= 1'b1
end
end
default :
endcase
end
endmodule
有问题可以补充。。。
首先PLL应用就不用说明了,这个直接调用内部软核来实现,没有涉及到代码。就分频代码我简单写个仿信8分频的代码,其他的大同小异。module div_8(clk_100M,rst,clk_125M)
input clk_100M,rst
output reg clk_125M//8分频输出12.5M
reg[3:0] temp
always@(posedge clk_100M or negedge rst)
begin
if(!rst)
begin
temp<=4'b0000
clk_125M<=1'孙物b0
end
else if(temp==4'd3)
begin
clk_125M<=~clk_125M
temp<=4'b0000
end
else
temp<=temp+1'b1
end
endmodule
这个只是8分则大液频代码,其他的16分频可参考这个来写,原理是一样的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)