module clock_1//顶层
(
input clk_ext,
input rst_n,
input key_starte,
input key_stop,
input key_sel,
output [7:0]seg_o,
output [3:0]sel_o
);
wire clk;
wire rst;
pll
pll_inst
(
.areset(~rst_n),
.inclk0(clk_ext),
.c0(clk),
.locked(rst)
);
pro_t
pro_t_inst
(
.clk(clk_ext),
.rst(rst_n),
.key_starte(key_starte),
.key_stop(key_stop),
.key_sel(key_sel),
.key_starte_1(key_starte_1),
.key_stop_1(key_stop_1),
.key_sel_1(key_sel_1)
);
clv
clv_inst
(
.clk(clk),
.rst(rst),
.out1(out1),
.out2(out2)
);
wire [7:0]a1;
wire [7:0]a2;
wire [7:0]a3;
wire [7:0]a4;
snain_st
snain_st_inst
(
.clk(clk_ext),
.rst(rst_n),
.key_starte(key_starte_1),
.key_stop(key_stop_1),
.key_sel(key_sel_1),
.key1(out1),
.a1(a1),
.a2(a2),
.a3(a3),
.a4(a4)
);
wire [15:0]q1;
wire [15:0]q2;
wire [15:0]q3;
wire [15:0]q4;
//1
rom_1
rom_1_inst
(
.address(a1),
.clock(clk),
.q(q1)
);
//2
rom_1
rom_2_inst
(
.address(a3),
.clock(clk),
.q(q3)
);
//3
rom_2
rom_3_inst
(
.address(a2),
.clock(clk),
.q(q2)
);
//4
rom_2
rom_4_inst
(
.address(a4),
.clock(clk),
.q(q4)
);
//--------------------------------------
sm
sm_inst
(
.clk(clk),
.rst(rst),
.clock(out2),
.seg_1(q1),
.seg_2(q2),
.seg_3(q3),
.seg_4(q4),
.seg_8(seg_o),
.sel(sel_o)
);
endmodule
//-----------------------分频
module clv
(
input clk,
input rst,
output out1, //10毫秒
output out2//3毫秒
);
parameter PI=16'd50000-1;
reg [15:0]cont;
always@(posedge clk or negedge rst)
begin
if(~rst)
cont<=1'b0;
else if(cont==PI)
cont<=1'b0;
else
cont<=cont+1'b1;
end
reg clk1;
always@(posedge clk or negedge rst)
begin
if(~rst)
clk1<=1'b0;
else if(cont==PI)
clk1<=1'b1;
else
clk1<=1'b0;
end
assign out1=clk1;
//------------------------------------------
reg [15:0]cont1;
always@(posedge clk or negedge rst)
begin
if(~rst)
cont1<=1'b0;
else if(cont1==2*(PI+1)/10-1)
cont1<=1'b0;
else
cont1<=cont1+1'b1;
end
reg clk2;
always@(posedge clk or negedge rst)
begin
if(~rst)
clk2<=1'b0;
else if(cont1==2*(PI+1)/10-1)
clk2<=1'b1;
else
clk2<=1'b0;
end
assign out2=clk2;
endmodule
//--------------------------------------按键
module pro_t
(
input clk,
input rst,
input key_starte,
input key_stop,
input key_sel,
output key_starte_1,
output key_stop_1,
output key_sel_1
);
reg pro;
wire key_starte_out;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro<=1'b0;
else
pro<=key_starte;
end
reg pro_1;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_1<=1'b0;
else
pro_1<=pro;
end
reg pro_2;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_2<=1'b0;
else
pro_2<=pro_1;
end
reg pro_7;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_7<=1'b0;
else
pro_7<=pro_2&(~pro_1);
end
assign key_starte_out=pro_7;
reg pro_3;
wire key_stop_out;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_3<=1'b0;
else
pro_3<=key_stop;
end
reg pro_4;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_4<=1'b0;
else
pro_4<=pro_3;
end
reg pro_5;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_5<=1'b0;
else
pro_5<=pro_4;
end
reg pro_6;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_6<=1'b0;
else
pro_6<=pro_5&(~pro_4);
end
assign key_stop_out=pro_6;
assign key_starte_1=key_starte_out;
assign key_stop_1=key_stop_out;
//----------------------------------------------
reg pro_sel;
wire key_sel_out;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_sel<=1'b0;
else
pro_sel<=key_sel;
end
reg pro_sel1;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_sel1<=1'b0;
else
pro_sel1<=pro_sel;
end
reg pro_sel2;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_sel2<=1'b0;
else
pro_sel2<=pro_sel1;
end
reg pro_sel3;
always@(posedge clk or negedge rst)
begin
if(~rst)
pro_sel3<=1'b0;
else
pro_sel3<=pro_sel2&(~pro_sel1);
end
assign key_sel_out=pro_sel3;
assign key_sel_1=key_sel_out;
endmodule
//------------------------------------------------状态转换
module snain_st
(
input clk,
input rst,
input key_starte,
input key_stop,
input key_sel,
input key1,//10毫秒1脉冲
output [7:0]a1,
output [7:0]a2,
output [7:0]a3,
output [7:0]a4
);
parameter IDLE=3'b000;
parameter WORK1=3'b001;
parameter WORK2=3'b010;
parameter STOP=3'b011;
reg [2:0]st;
reg [2:0]st_next;
always@(posedge clk or negedge rst)
begin
if(~rst)
st<=IDLE;
else
st<=st_next;
end
always@(*)
begin
if(~rst)
st_next=IDLE;
else
case(st)
IDLE:if(key_starte==1)
st_next=WORK1;
else
st_next=IDLE;
WORK1:if(key_stop==1)
st_next=STOP;
else if(key_sel==1)
st_next=WORK2;
else
st_next=WORK1;
WORK2:if(key_stop==1)
st_next=STOP;
else if(key_sel==1)
st_next=WORK1;
else
st_next=WORK2;
STOP:if(key_starte==1)
st_next=WORK1;
else
st_next=STOP;
default:st_next=IDLE;
endcase
end
//-----------------------------------------------
reg [7:0]cont1;
reg [7:0]cont_1;
reg [7:0]cont2;
reg [7:0]cont_2;
//1
always@(posedge clk or negedge rst)
begin
if(~rst)
begin
cont1<=8'd0;
cont_1<=8'd100;
cont2<=8'd0;
cont_2<=8'd60;
end
else
case(st_next)
IDLE:
begin
cont1<=8'd0;
cont_1<=8'd100;
cont2<=8'd0;
cont_2<=8'd60;
end
WORK1:
begin
begin
if(cont1==8'd99&&key1==1'b1)
cont1<=8'd0;
else if(key1==1'b1)
cont1<=cont1+1'b1;
end
begin
if(cont2==8'd59&&cont1==8'd99&&key1==1)
cont2<=8'b0;
else if(key1==1&&cont1==8'd99)
cont2<=cont2+1'b1;
end
begin
cont_1<=cont_1;
cont_2<=cont_2;
end
end
WORK2:
begin
begin
if(cont_1==8'd199&&key1==1'b1)
cont_1<=8'd100;
else if(key1==1'b1)
cont_1<=cont_1+1'b1;
end
begin
if(cont_2==8'd119&&cont_1==8'd199&&key1==1)
cont_2<=8'd60;
else if(key1==1&&cont_1==8'd199)
cont_2<=cont_2+1'b1;
end
begin
cont1<=cont1;
cont2<=cont2;
end
end
STOP:
begin
cont1<=cont1;
cont2<=cont2;
cont_1<=cont_1;
cont_2<=cont_2;
end
default:begin
cont1<=8'd0;
cont_1<=8'd100;
cont2<=8'd0;
cont_2<=8'd60;
end
endcase
end
assign a1=cont1;
assign a3=cont_1;
assign a2=cont2;
assign a4=cont_2;
endmodule
//--------------------------------------数码管扫描
module sm
(
input clk,
input rst,
input clock,//3毫秒1脉冲
input [15:0]seg_1,
input [15:0]seg_2,
input [15:0]seg_3,
input [15:0]seg_4,
output [7:0]seg_8,
output [3:0]sel
);
parameter IDEL=5'b00000;
parameter S1=5'b00001;
parameter S2=5'b00010;
parameter S3=5'b00100;
parameter S4=5'b01000;
reg [7:0]seg_7;
reg [3:0]sel_1;
reg [2:0]cont;
always@(posedge clk or negedge rst)
begin
if(~rst)
cont<=0;
else
begin
if(cont==3'd3&&clock==1'b1)
cont<=0;
else if(clock==1'b1)
cont<=cont+1'b1;
end
end
reg [4:0]current_state;
reg [4:0]next_state;
always@(posedge clk or negedge rst)
begin
if(~rst)
current_state<=IDEL;
else
current_state<=next_state;
end
always@(*)
begin
next_state=IDEL;
case(current_state)
IDEL:if(cont==0)
next_state=S1;
S1:if(cont==3'd1)
next_state=S2;
else
next_state=S1;
S2:if(cont==3'd2)
next_state=S3;
else
next_state=S2;
S3:if(cont==3'd3)
next_state=S4;
else
next_state=S3;
S4:if(cont==3'd0)
next_state=S1;
else
next_state=S4;
default:next_state=IDEL;
endcase
end
always@(posedge clk or negedge rst)
begin
if(~rst)
begin
seg_7<=8'b11_111_111;
sel_1<=4'b1111;
end
else
case(next_state)
IDEL:
begin
seg_7<=8'b11_111_111;
sel_1<=4'b1111;
end
S1:
begin
seg_7<=seg_1[7:0];
sel_1<=4'b1110;
end
S2:
begin
seg_7<=seg_3[15:8];
sel_1<=4'b1101;
end
S3:
begin
seg_7<=seg_2[7:0];
sel_1<=4'b1011;
end
S4:
begin
seg_7<=seg_4[15:8];
sel_1<=4'b0111;
end
default:
begin
seg_7<=11_111_111;
sel_1<=4'b1111;
end
endcase
end
assign seg_8=seg_7;
assign sel=sel_1;
endmodule
//------------------------------------测试
`timescale 1ns/1ns
module clock_1_tb;
reg clk;
reg rst;
reg key_starte;
reg key_stop;
reg sel;
wire [7:0]seg_1;
wire [3:0]sel_1;
initial
begin
clk=0;
rst=0;
#50 rst=1;
#2000000 $stop;
end
initial
begin
key_stop=1;
sel=1;
key_starte=1;
#1000 key_starte=0;
#20000 sel=0;
#100_000_00 key_stop=0;
end
always #20 clk<=~clk;
clock_1
clock_1_inst
(
.clk_ext(clk),
.rst_n(rst),
.key_starte(key_starte),
.key_stop(key_stop),
.key_sel(sel),
.seg_o(seg_1),
.sel_o(sel_1)
);
endmodule