首先需要分析題意,設計出模塊的輸入和輸出:
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