本人地大14級師兄,如果有學弟學妹搜到這個評論一個唄!
一、設計要求
編寫VerilogHDL程序,實現如下功能:
輸入時鐘信號和復位/信號,實現4分頻/5分頻,佔空比爲1:1.
二、設計思路
1.偶數分頻
假設爲N分頻,計數到N/2-1時,時鐘翻轉、計數清零,如此循環就可以得到N(偶)分頻
2.奇數分頻(佔空比爲50%)
(1)假設爲N分頻,取一個進行上升沿觸發的模N計數,觸發時鐘翻轉後,經過(N-1)/2再次進行翻轉,得到一個佔空比非50%奇數N頻時鐘。再取一個同時進行下降沿觸發的模N計數,觸發時鐘翻轉後,同樣經過(N-1)/2時,輸出時鐘再次翻轉生成佔空比非50%的奇數N分頻時鐘。兩個時鐘進行相或運算,得到佔空比爲50%的奇數n分頻時鐘。
(2)與(1)相似,取兩個都是上升沿觸發的模N計數,一個是(N-1)/2時翻轉,另一個是(N+1)/2時翻轉。兩個時鐘進行相或運算,得到佔空比爲50%的奇數n分頻時鐘。
(3)小數分頻
本次使用思路(1)
三、Verilog代碼及說明
1. 偶數分頻
module FreqDivFour(CLK , CLK_Out, rst); //四分頻,括號內只能是輸入輸出型
input CLK,rst;
output CLK_Out ;
reg[1:0] cnt;
reg CLK_Out ; //可爲寄存器輸出型
always@(posedge CLK or negedge rst)
begin
if(!rst) begin cnt<= 0; CLK_Out <= 0; end
else if(cnt == 1)
begin
CLK_Out<=~ CLK_Out; //時鐘翻轉
cnt<= 0; //計數清零
end
elsecnt <= cnt + 1;
end
endmodule
2. 奇數分頻(佔空比爲50%)
module FreqDivFive(CLK , CLK_Out, rst); //五分頻
input CLK,rst;
output CLK_Out ;
reg[2:0] cnt_One, cnt_Two;
reg CLK_One,CLK_Two;
always@(posedge CLK or negedge rst) //上升沿觸發
begin
if(!rst) begin cnt_One <= 0; CLK_One <=0; end
else
begin
if(cnt_One== 4)
cnt_One<= 0; //計數清零
else
cnt_One<= cnt_One + 1;
if(cnt_One== 1)
CLK_One<=~ CLK_One; //時鐘翻轉
elseif(cnt_One == 3)
CLK_One<=~ CLK_One; //時鐘翻轉
end
end
always@(negedge CLK or negedge rst) //下降沿觸發
begin
if(!rst) begin cnt_Two <= 0; CLK_Two <= 0; end
else
begin
if(cnt_Two== 4)
cnt_Two<= 0; //計數清零
else
cnt_Two<= cnt_Two + 1;
if(cnt_Two== 1)
CLK_Two<=~CLK_Two; //時鐘翻轉
elseif(cnt_Two == 3)
CLK_Two<=~CLK_Two; //時鐘翻轉
end
end
assign CLK_Out = CLK_One | CLK_Two; //兩輸出波形相或運算,assign只能是net型
endmodule
四、實驗結果及分析
1.偶數分頻
2.奇數分頻(佔空比爲50%)
附件:modelsim測試代碼
// Generated on "03/22/201721:49:38"
// Verilog Test Bench template for design :FreqDivFour
//
// Simulation tool : ModelSim-Altera (Verilog)
//
`timescale 1 ps/ 1 ps
module FreqDivFour_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK;
reg rst;
// wires
wire CLK_Out;
// assign statements (if any)
FreqDivFour i1 (
// port map - connection between masterports and signals/registers
.CLK(CLK),
.CLK_Out(CLK_Out),
.rst(rst)
);
initial
begin
// code that executes only once
// insert code here --> begin
CLK= 0;
forever
#10CLK=~CLK;
// --> end
$display("Runningtestbench");
end
initial
begin
rst = 0;
#1000 rst=1;
#1000;
$stop;
end
always
// optional sensitivity list
// @(event1 or event2 or .... eventn)
begin
// code executes for every event on sensitivitylist
// insert code here --> begin
@eachvec;
// --> end
end
endmodule