FPGA延時 Verilog HDL 實現(xiàn)
時間:2025-11-16 22:54:11
手機看文章
掃描二維碼
隨時隨地手機看文章
本章節(jié) 簡介:
可以在任意時刻啟動,可以重復啟動,延時時長可調,單位可切換(ms/us),在50MHz時鐘下的延時范圍是1ms-85899ms/1us-85899us。
源代碼和modelsim仿真代碼:
module delay //#(parameter N ) //可以延時N*1ms/us (input clk,rst_n, input start, //start上升沿有效 input delay_unit, //延時單位,high:ms/low:us output finish,finish_pose); //finish上升沿有效 reg start_reg0,start_reg1; //start兩級緩存,用于邊沿檢測 reg finish_reg0,finish_reg1; //finish兩級緩存 reg [31:0]cnt; //固定32位寬計數(shù) reg [31:0]cnt_full; reg restart; //重新開始 wire start_pose,full; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 32'd0; cnt_full <= 32'd10; //避免一開始finish置位 restart <= 1'b0; start_reg0 <= 1'b0; start_reg1 <= 1'b0; finish_reg0 <= 1'b0; finish_reg1 <= 1'b0; end else begin start_reg0 <= start; start_reg1 <= start_reg0; finish_reg1 <= finish_reg0; /**檢測計時單位**/ if(delay_unit) cnt_full <= 32'd50_000*2-32'd2; //計時2ms 實際例化時用N代替: 32'd50_000*N-32'd2 else cnt_full <= 32'd50*2-32'd2; //計時2us /***************/ /**是否重新開始**/ if(start_pose) //檢測到起始時刻 restart <= 1'b1; /****計時完成****/ else if(full) //延時結束 begin cnt <= 32'd0; //cnt歸零 finish_reg0 <= 1'b1; //finish響應 restart <= 1'b0; end /***************/ /****計時開始****/ else if(restart) begin finish_reg0 <= 1'b0; //新一輪延時finish復位 cnt <= cnt+1'b1; end /***************/ /**等待新一輪計時**/ else begin cnt <= cnt; finish_reg0 <= finish_reg0; restart <= restart; end end end assign start_pose = (~start_reg1&start_reg0)?1'b1:1'b0; //start上升沿檢測 assign finish_pose = (~finish_reg1&finish_reg0)?1'b1:1'b0; //finish上升沿檢測 assign full = (cnt_full-cnt==0)?1'b1:1'b0; //檢測是否計滿 assign finish = finish_reg0; endmodule /**************************************************************************************************/ /***************************************modelsim********************************************/ `timescale 1ns/1ps module delay_tb(); reg clk,rst_n; reg start; wire finish,finish_pose; delay delay_u0 (.clk(clk), .rst_n(rst_n), .start(start), .delay_unit(1'b1), .finish(finish), .finish_pose(finish_pose)); //defparam delay_u0.N = 2; //延時2ms initial begin clk = 1'b0; rst_n = 1'b0; start = 1'b0; #1000 rst_n = 1'b1; #4010 start = 1'b1; #50 start = 1'b0; end always #10 clk = ~clk; endmodule
思路:
start端口給上升沿啟動延時,延時結束端口finish置位(重新啟動延時后復位)、finish的上升沿檢測在模塊內(nèi)部已做好(端口finish_pose),直接調用即可,端口delay_unit置高選擇ms,置低選擇us,#(參數(shù)N )“是計時時長,例如計時8ms:”N = 8, .delay_unit(1'b1)“,實際例化時只需”defparam 例化名.N = 數(shù)值”。因為modelsim無法識別這種調用,所以直接用數(shù)值代替N進行測試。邊沿檢測會消耗兩個時鐘周期,所以cnt_full需要減2,并且將finish_reg0直接連到finish輸出端口而不是用finish_reg1連接完成。
延時2ms測試的起始時刻(5010ns)和結束時刻(2005010ns):







