用ROM做秒表计时器,和倒计时

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
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yang_wei_bk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值