展銳秒計數器


 

 

 

首先需要分析題意,設計出模塊的輸入和輸出:

 

 

1.此題中的32.768Khz是個很有意思的頻率,在日常使用中,32.768Khz比較容易分頻以便於產生1s的時鍾頻率,1s/(1/32768)=32768,對於32.768Khz計數一秒鍾需要計數32768個時鍾周期=2^15,設置一個15位的計數器,當其溢出時即是1s。

2.異步復位低電平有效,注意題中提及已經與時鍾上升沿同步,不需要進行異步復位同步釋放的處理。

3.start信號只持續一個時鍾周期,所以需要產生計數使能信號

4.計數到預定值時,產生一個時鍾周期的int_pluse,計數器清零並停止。

 

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: connor jiao
// Create Date: 10:45 2020/6/14
// Design Name: 
// Module Name: 
// Function   : 請用Verilog RTL描述如下圖設計:以clk為基准,設計一個秒計數器,在指定的計數值產生中斷,實時輸出當前的秒數計數值。(紫光展銳數字IC崗)
//<1>clk是時鍾輸入,頻率為32.768KHz。
//<2>rst_n是異步復位輸入,低電平有效,復位整個系統,為高則整個系統開始工作,其上升沿已經同步於clk。
//<3>start是啟動信號,一個clk時鍾周期的正脈沖,同步於clk。alarm[7:0]是配置信息,單位為秒,同步於clk。
//<4>工作模式:收到start后,秒計數器sec_cnt從零開始以秒為單位來計數,計數到alarm[7:0]指定的數值時,產生一個int pluse(時鍾周期的正脈沖),秒數計數器回零並停止。
// Revision 0.01 - File Created
// Additional Comments:
//////////////////////////////////////////////////////////////////////////////////
module seconds_counter(
                        clk,
                        rst_n,
                        start,
                        alarm,
                        int_pluse,
                        sec_cnt
                        );
    input clk;
    input rst_n;
    input start;
    input [7:0]alarm;
    output reg int_pluse;
    output reg [7:0]sec_cnt;
    //
    reg [7:0]alarm_r;
    reg [14:0]cnt1s;
    //對輸入的信號進行寄存,防止操作過程中發生改變
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            alarm_r<=8'd0;
        else if(start)
            alarm_r<=alarm;
        else
            alarm_r<=alarm_r;
    end
    //cnt_en
    reg cnt_en;
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            cnt_en<=1'b0;
        else if(start==1'b1)
            cnt_en<=1'b1;
        else if(sec_cnt==alarm_r&&cnt1s==32767)
            cnt_en<=1'b0;
        else
            cnt_en<=cnt_en;
    end
    
    //
    
    
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            cnt1s<='d0;
        else if(cnt_en)
            cnt1s<=cnt1s+1'b1;
        else
            cnt1s<='d0;
    end
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            sec_cnt<='d0;
        else if(sec_cnt==alarm_r&&cnt1s==32767)
            sec_cnt<='d0;//計數滿清零,cnt_en控制計數滿停止
        else if(cnt1s==32767)
            sec_cnt<=sec_cnt+1'b1;
        else
            sec_cnt<=sec_cnt;
    end
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            int_pluse<=1'b0;
        else if(sec_cnt==alarm_r&&cnt1s==32767)
            int_pluse<=1'b1;
        else
            int_pluse<=1'b0;
    end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: connor jiao
// Create Date: 
// Design Name: 
// Module Name: 
// Function   :  
// Revision 0.01 - File Created
// Additional Comments:
//////////////////////////////////////////////////////////////////////////////////
module seconds_counter_tb();
    
    reg clk;
    reg rst_n;
    reg start;
    reg [7:0]alarm;
    wire int_pluse;
    wire [7:0]sec_cnt;
    seconds_counter seconds_counter(
                        .clk(clk),
                        .rst_n(rst_n),
                        .start(start),
                        .alarm(alarm),
                        .int_pluse(int_pluse),
                        .sec_cnt(sec_cnt)
                        );
    initial clk=0;
    always #1 clk=~clk;
    initial begin
        rst_n=0;
        alarm=0;
        start=0;
        #201;
        rst_n=1;
        #201;
        start=1'b1;
        alarm=8'd13;
        #2;
        start=1'b0;
        
    end
endmodule
View Code

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM