找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5404|回复: 1
收起左侧

EDA设计数字频率计(Verilog源程序)

[复制链接]
ID:343799 发表于 2019-6-25 22:26 | 显示全部楼层 |阅读模式
最近在做数电研究,题目为数字频率计,要求用FPGA板子设计,为了能使51黑电子论坛能发展的更好,我也贡献我的一份力量,希望能帮到各位。

原理:测量1s时间内待测脉冲个数从而得出待测信号的频率。
具体模块:
基准信号产生模块:把50MHz分频成1Hz

控制模块:产生计数使能信号;产生清零信号;
计数模块:通过从控制模块输入进来的使能信号和清零信号能从0000~1001计数(8421码),并能产生进位;
锁存模块:把计数结果锁存;使显示模块能稳定显示结果
显示模块:通过数码管显示,位选是用的外部电路138译码器,段选是一个四位二进制码(8421码)
待测信号:由于本人没有函数信号发生器所以就把50MHz分成900Hz作为待测信号来验证该系统能否正确测量,也可以把该模块删掉,把输出口接一个input,就可以测量外部信号了,

由于板子资源有限,而我的程序有点复杂,不是很简洁,所以只能显示四位结果,即量程为0~9999Hz。板子上有8位数码管,理论上可以显示8位结果,即量程为0~99999999Hz。另外我准备用modelsim仿真各个模块,在我仿真完控制模块后遇到了问题,其他几个模块仿真不出来,只有控制模块可以仿真,其他几个写了激励信号,而且都赋了初值,但是输出结果一直是高阻态(显示红线),希望各位朋友能教教我(本人不怎么会用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. //计数模块
  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;//计数清零
  23. else if(en)
  24. begin if(out==9)
  25.                 out=0;
  26. else out<=out+1;//计数
  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为分频系数,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为偶数
  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为奇数
  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为偶数,备用时钟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. //数码管显示模块
  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
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1045091 发表于 2022-9-18 13:11 | 显示全部楼层
有测试文件吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表