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







