|
最近在做數(shù)電研究,題目為數(shù)字頻率計(jì),要求用FPGA板子設(shè)計(jì),為了能使51黑電子論壇能發(fā)展的更好,我也貢獻(xiàn)我的一份力量,希望能幫到各位。
原理:測(cè)量1s時(shí)間內(nèi)待測(cè)脈沖個(gè)數(shù)從而得出待測(cè)信號(hào)的頻率。
具體模塊:
基準(zhǔn)信號(hào)產(chǎn)生模塊:把50MHz分頻成1Hz
控制模塊:產(chǎn)生計(jì)數(shù)使能信號(hào);產(chǎn)生清零信號(hào);
計(jì)數(shù)模塊:通過從控制模塊輸入進(jìn)來(lái)的使能信號(hào)和清零信號(hào)能從0000~1001計(jì)數(shù)(8421碼),并能產(chǎn)生進(jìn)位;
鎖存模塊:把計(jì)數(shù)結(jié)果鎖存;使顯示模塊能穩(wěn)定顯示結(jié)果
顯示模塊:通過數(shù)碼管顯示,位選是用的外部電路138譯碼器,段選是一個(gè)四位二進(jìn)制碼(8421碼)
待測(cè)信號(hào):由于本人沒有函數(shù)信號(hào)發(fā)生器所以就把50MHz分成900Hz作為待測(cè)信號(hào)來(lái)驗(yàn)證該系統(tǒng)能否正確測(cè)量,也可以把該模塊刪掉,把輸出口接一個(gè)input,就可以測(cè)量外部信號(hào)了,
由于板子資源有限,而我的程序有點(diǎn)復(fù)雜,不是很簡(jiǎn)潔,所以只能顯示四位結(jié)果,即量程為0~9999Hz。板子上有8位數(shù)碼管,理論上可以顯示8位結(jié)果,即量程為0~99999999Hz。另外我準(zhǔn)備用modelsim仿真各個(gè)模塊,在我仿真完控制模塊后遇到了問題,其他幾個(gè)模塊仿真不出來(lái),只有控制模塊可以仿真,其他幾個(gè)寫了激勵(lì)信號(hào),而且都賦了初值,但是輸出結(jié)果一直是高阻態(tài)(顯示紅線),希望各位朋友能教教我(本人不怎么會(huì)用modelsim)
38]E7N6BZF22`N0)5Y%UD00.png (8.03 KB, 下載次數(shù): 117)
下載附件
頂層
2019-6-25 19:04 上傳
源程序:
- //控制模塊
- module fre_ctrl(clk,rst,count_en,count_clr,load);
- input clk,rst;
- output count_en,count_clr,load;
- reg count_en=0;
- reg load=0;
- always@(posedge clk)
- begin if(rst)begin count_en<=0;load<=1;end
- else begin count_en<=~count_en;
- load<=count_en;
- end
- end
- assign count_clr=(~clk)&load;
- endmodule
- //計(jì)數(shù)模塊
- module count10(out,cout,en,clr,clk);
- input en,clr,clk;
- output[3:0] out;
- output cout;
- reg[3:0] out;
- always @(negedge clk or posedge clr)
- begin if(clr) out<=0;//計(jì)數(shù)清零
- else if(en)
- begin if(out==9)
- out=0;
- else out<=out+1;//計(jì)數(shù)
- end
- end
- assign cout=((out==9)&en)?1:0;
- endmodule
- //鎖存模塊
- module latch_16(qo,din,load);
- input load;
- input[15:0] din;
- output [15:0] qo;
- reg[15:0] qo;
- always @(posedge load)
- begin qo=din;end
- endmodule
- //1Hz基準(zhǔn)信號(hào)產(chǎn)生模塊(該模塊是我在網(wǎng)上找的,可以把50MHz分成任意小于50M的頻率)
- module div_N(
- input CLK,// 基準(zhǔn)時(shí)鐘
- output CLK_div_N// N分頻后得到的時(shí)鐘
- );
- wire[31:0]N=50000000;// N為分頻系數(shù),N≥2即可,N的值為CLK除以CLK_div_N后取整(四舍五入)
- /******************** 產(chǎn)生備用時(shí)鐘1 ***************/
- reg[31:0]cnt1;
- reg CLK_div_N_1;
- always @ (posedge CLK)
- begin
- if(N%2==0)// 如果N為偶數(shù)
- begin
- if(N==2)// 如果N為2
- CLK_div_N_1 <= ~CLK_div_N_1;
- else
- begin
- if(cnt1==(N-2)/2)
- begin
- cnt1 <= 0;
- CLK_div_N_1 <= ~CLK_div_N_1;
- end
- else
- cnt1 <= cnt1+1;
- end
- end
- else// 如果N為奇數(shù)
- begin
- if(cnt1==N-1)
- cnt1 <= 0;
- else
- cnt1 <= cnt1+1;
- if((cnt1==N-1) || (cnt1==(N-1)/2))
- CLK_div_N_1 <= ~CLK_div_N_1;
- else ;
- end
- end
- /*********************** 產(chǎn)生備用時(shí)鐘2 *********************/
- wire CLK0=(N%2)? (~CLK):0;// 如果N為偶數(shù),備用時(shí)鐘2(CLK_div_N_2)恒為0,即不需要用到此備用時(shí)鐘
- reg[31:0]cnt2;
- reg CLK_div_N_2;
- always @ (posedge CLK0)
- begin
- if(cnt2==N-1)
- cnt2 <= 0;
- else
- cnt2 <= cnt2+1;
- if((cnt2==N-1) || (cnt2==(N-1)/2))
- CLK_div_N_2 <= ~CLK_div_N_2;
- end
- /******************** 產(chǎn)生最終分頻時(shí)鐘************************/
- assign CLK_div_N = CLK_div_N_1 | CLK_div_N_2;
- endmodule
- //待測(cè)信號(hào)(本人設(shè)置的輸出900Hz)
- module square(nrst,clk_in,clk_out);
- input wire nrst;
- input wire clk_in;
- output reg clk_out;
- reg [18:0]r_cnt;
- always @(posedge clk_in)
- if(nrst)
- begin
- if(r_cnt < 19'd27776)
- r_cnt <= r_cnt+1'b1;
- else begin
- r_cnt <= 19'b0;
- clk_out <= ~clk_out;
- end
- end
- else begin
- r_cnt <= 19'b0;
- clk_out <= 1'b0;
- end
- endmodule
- //數(shù)碼管顯示模塊
- module SMG(qo,clk,rst,se,sel);
- input wire clk,rst;
- input[15:0]qo;
- output reg [7:0]se;
- output reg [2:0]sel;
- reg [3:0]ge;
- reg [3:0]shi;
- reg [3:0]bai;
- reg [3:0]qian;
- reg [7:0]b;
- reg c;
- reg [25:0]q;
- reg [3:0]a;
- always@(posedge clk or negedge rst)
- begin
- if(rst==0)
- begin
- q<=0;
- c<=0;
- end
- else if(q==139999)
- begin
- q<=0;
- c<=~c;
- end
- else
- q<=q+1;
- end
- always@(posedge c)
- begin
- if(a==3)
- a<=0;
- else
- a<=a+1;
- end
- always@(*)
- begin
- case(a)
- 0:begin
- sel=3'b011;
- qian={qo[15],qo[14],qo[13],qo[12]};b=ge;
- end
- 1:begin
- sel=3'b010;
- bai={qo[11],qo[10],qo[9],qo[8]};b=shi;
- end
- 2:begin
- sel=3'b001;
- shi={qo[7],qo[6],qo[5],qo[4]};b=bai;
- end
- 3:begin
- sel=3'b000;
- ge={qo[3],qo[2],qo[1],qo[0]};b=qian;
- end
- default sel=3'b011;
- endcase
- end
- always@(posedge clk)
- begin
- case(b)
- 4'b0000:se=8'b0011_1111;//0
- 4'b0001:se=8'b0000_0110;//1
- 4'b0010:se=8'b0101_1011;//2
- 4'b0011:se=8'b0100_1111;//3
- 4'b0100:se=8'b0110_0110;//4
- 4'b0101:se=8'b0110_1101;//5
- 4'b0110:se=8'b0111_1101;//6
- 4'b0111:se=8'b0000_0111;//7
- 4'b1000:se=8'b0111_1111;//8
- 4'b1001:se=8'b0110_1111;//9
- endcase
- end
- endmodule
復(fù)制代碼 |
評(píng)分
-
查看全部評(píng)分
|