標題: EDA設計數(shù)字頻率計(Verilog源程序) [打印本頁]

作者: 熊大946    時間: 2019-6-25 22:26
標題: EDA設計數(shù)字頻率計(Verilog源程序)
最近在做數(shù)電研究,題目為數(shù)字頻率計,要求用FPGA板子設計,為了能使51黑電子論壇能發(fā)展的更好,我也貢獻我的一份力量,希望能幫到各位。

原理:測量1s時間內待測脈沖個數(shù)從而得出待測信號的頻率。
具體模塊:
基準信號產生模塊:把50MHz分頻成1Hz

控制模塊:產生計數(shù)使能信號;產生清零信號;
計數(shù)模塊:通過從控制模塊輸入進來的使能信號和清零信號能從0000~1001計數(shù)(8421碼),并能產生進位;
鎖存模塊:把計數(shù)結果鎖存;使顯示模塊能穩(wěn)定顯示結果
顯示模塊:通過數(shù)碼管顯示,位選是用的外部電路138譯碼器,段選是一個四位二進制碼(8421碼)
待測信號:由于本人沒有函數(shù)信號發(fā)生器所以就把50MHz分成900Hz作為待測信號來驗證該系統(tǒng)能否正確測量,也可以把該模塊刪掉,把輸出口接一個input,就可以測量外部信號了,

由于板子資源有限,而我的程序有點復雜,不是很簡潔,所以只能顯示四位結果,即量程為0~9999Hz。板子上有8位數(shù)碼管,理論上可以顯示8位結果,即量程為0~99999999Hz。另外我準備用modelsim仿真各個模塊,在我仿真完控制模塊后遇到了問題,其他幾個模塊仿真不出來,只有控制模塊可以仿真,其他幾個寫了激勵信號,而且都賦了初值,但是輸出結果一直是高阻態(tài)(顯示紅線),希望各位朋友能教教我(本人不怎么會用modelsim)

源程序:
  1. //控制模塊
  2. module fre_ctrl(clk,rst,count_en,count_clr,load);
  3. input clk,rst;
  4. output count_en,count_clr,load;
  5. reg count_en=0;
  6. reg load=0;
  7. always@(posedge clk)
  8.         begin if(rst)begin count_en<=0;load<=1;end
  9.         else begin count_en<=~count_en;
  10.                                 load<=count_en;
  11.                   end
  12.         end
  13.         assign count_clr=(~clk)&load;
  14.         endmodule


  15. //計數(shù)模塊
  16. module count10(out,cout,en,clr,clk);
  17. input en,clr,clk;
  18. output[3:0] out;
  19. output cout;
  20. reg[3:0] out;
  21. always @(negedge clk or posedge clr)
  22. begin if(clr) out<=0;//計數(shù)清零
  23. else if(en)
  24. begin if(out==9)
  25.                 out=0;
  26. else out<=out+1;//計數(shù)
  27. end
  28. end
  29. assign cout=((out==9)&en)?1:0;
  30. endmodule

  31. //鎖存模塊
  32. module latch_16(qo,din,load);
  33. input load;
  34. input[15:0] din;
  35. output [15:0] qo;
  36. reg[15:0] qo;
  37. always @(posedge load)
  38. begin qo=din;end
  39. endmodule

  40. //1Hz基準信號產生模塊(該模塊是我在網上找的,可以把50MHz分成任意小于50M的頻率)
  41. module div_N(
  42. input CLK,// 基準時鐘
  43. output CLK_div_N// N分頻后得到的時鐘
  44. );
  45. wire[31:0]N=50000000;// N為分頻系數(shù),N≥2即可,N的值為CLK除以CLK_div_N后取整(四舍五入)
  46. /******************** 產生備用時鐘1 ***************/
  47. reg[31:0]cnt1;
  48. reg CLK_div_N_1;
  49. always @ (posedge CLK)
  50. begin
  51. if(N%2==0)// 如果N為偶數(shù)
  52. begin
  53. if(N==2)// 如果N為2
  54. CLK_div_N_1 <= ~CLK_div_N_1;
  55. else
  56. begin
  57. if(cnt1==(N-2)/2)
  58. begin
  59. cnt1 <= 0;
  60. CLK_div_N_1 <= ~CLK_div_N_1;
  61. end
  62. else
  63. cnt1 <= cnt1+1;
  64. end
  65. end
  66. else// 如果N為奇數(shù)
  67. begin
  68. if(cnt1==N-1)
  69. cnt1 <= 0;
  70. else
  71. cnt1 <= cnt1+1;
  72. if((cnt1==N-1) || (cnt1==(N-1)/2))
  73. CLK_div_N_1 <= ~CLK_div_N_1;
  74. else ;
  75. end
  76. end
  77. /*********************** 產生備用時鐘2 *********************/
  78. wire CLK0=(N%2)? (~CLK):0;// 如果N為偶數(shù),備用時鐘2(CLK_div_N_2)恒為0,即不需要用到此備用時鐘
  79. reg[31:0]cnt2;
  80. reg CLK_div_N_2;
  81. always @ (posedge CLK0)
  82. begin
  83. if(cnt2==N-1)
  84. cnt2 <= 0;
  85. else
  86. cnt2 <= cnt2+1;
  87. if((cnt2==N-1) || (cnt2==(N-1)/2))
  88. CLK_div_N_2 <= ~CLK_div_N_2;
  89. end
  90. /******************** 產生最終分頻時鐘************************/
  91. assign CLK_div_N = CLK_div_N_1 | CLK_div_N_2;
  92. endmodule

  93. //待測信號(本人設置的輸出900Hz)
  94. module square(nrst,clk_in,clk_out);
  95. input wire nrst;
  96. input wire clk_in;
  97. output reg clk_out;
  98. reg [18:0]r_cnt;

  99. always @(posedge clk_in)
  100. if(nrst)
  101. begin
  102. if(r_cnt < 19'd27776)
  103. r_cnt <= r_cnt+1'b1;
  104. else begin
  105. r_cnt <= 19'b0;
  106. clk_out <= ~clk_out;
  107. end
  108. end
  109. else begin
  110. r_cnt <= 19'b0;
  111. clk_out <= 1'b0;
  112. end
  113. endmodule

  114. //數(shù)碼管顯示模塊
  115. module SMG(qo,clk,rst,se,sel);
  116. input wire clk,rst;
  117. input[15:0]qo;
  118. output reg [7:0]se;
  119. output reg [2:0]sel;
  120. reg [3:0]ge;
  121. reg [3:0]shi;
  122. reg [3:0]bai;
  123. reg [3:0]qian;
  124. reg [7:0]b;
  125. reg c;
  126. reg [25:0]q;
  127. reg [3:0]a;
  128. always@(posedge clk or negedge rst)
  129. begin

  130. if(rst==0)
  131. begin
  132. q<=0;
  133. c<=0;
  134. end
  135. else if(q==139999)
  136. begin
  137. q<=0;
  138. c<=~c;
  139. end
  140. else
  141. q<=q+1;
  142. end

  143. always@(posedge c)
  144. begin
  145.     if(a==3)
  146.     a<=0;
  147.     else
  148.     a<=a+1;
  149. end

  150. always@(*)
  151. begin
  152. case(a)
  153. 0:begin
  154. sel=3'b011;
  155. qian={qo[15],qo[14],qo[13],qo[12]};b=ge;
  156. end
  157. 1:begin
  158. sel=3'b010;
  159. bai={qo[11],qo[10],qo[9],qo[8]};b=shi;
  160. end
  161. 2:begin
  162. sel=3'b001;
  163. shi={qo[7],qo[6],qo[5],qo[4]};b=bai;
  164. end
  165. 3:begin
  166. sel=3'b000;
  167. ge={qo[3],qo[2],qo[1],qo[0]};b=qian;
  168. end
  169. default sel=3'b011;
  170. endcase
  171. end

  172. always@(posedge clk)
  173. begin
  174. case(b)
  175. 4'b0000:se=8'b0011_1111;//0
  176. 4'b0001:se=8'b0000_0110;//1
  177. 4'b0010:se=8'b0101_1011;//2
  178. 4'b0011:se=8'b0100_1111;//3
  179. 4'b0100:se=8'b0110_0110;//4
  180. 4'b0101:se=8'b0110_1101;//5
  181. 4'b0110:se=8'b0111_1101;//6
  182. 4'b0111:se=8'b0000_0111;//7
  183. 4'b1000:se=8'b0111_1111;//8
  184. 4'b1001:se=8'b0110_1111;//9
  185. endcase
  186. end

  187. endmodule
復制代碼

作者: 666GAO    時間: 2022-9-18 13:11
有測試文件嗎





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1