-

问题来源

​ 当时我在设计FPGA简易频率计的时候,当编写完等精度测量的频率计算模块的时候,编译综合并没有出现错误,然后将我之前编写的Seg数码管驱动模块导入到项目里面,单独编译综合也是没有问题。但是,当我设计顶层模块并实例化频率计算模块和Seg驱动模块的时候,报错显示逻辑资源不够用!

​ 那么就奇了怪了,在野火视频教程里面freq_meter_calc模块的资源使用情况并没有这么多,视频显示为2606,而我的使用情况是4436,这个模块的使用量就占据我开发板总资源量的**69%**!!

并没有解决。不是知道是什么原因,不管怎么样,我要让代码能成功运行的话只能降低寄存器的位宽了,这样会导致测量的频率范围降低。

资源使用情况

代码

顶层模块

freq_meter.v
module freq_meter ( input wire sys_clk , //系统时钟,频率50MHz input wire sys_rst_n , //复位信号,低电平有效 input wire clk_test, output wire [7:0]segdata, output wire [2:0]segcs ); //wire define wire [33:0] freq ; //计算得到的待检测信号时钟频率 //------------- freq_meter_calc_inst -------------- freq_meter_calc freq_meter_calc_inst ( .sys_clk (sys_clk ), //系统时钟,频率50MHz .sys_rst_n (sys_rst_n ), //复位信号,低电平有效 .clk_test (clk_test ), //待检测时钟 .freq (freq ) //待检测时钟频率 ); //------------- seg_595_dynamic_inst -------------- seg seg_inst ( .clk(sys_clk), .rst_n(sys_rst_n), .tenvalue(freq), // 这里连接没有问题 .segdata(segdata), .segcs(segcs) ); endmodule

数码管驱动模块

seg.v
/* 数码管显示驱动,目前是直接设置固定数据 通过将tenvalue设置到输入端口,可以作为子模块,通过传入数据显示在数码管上面 */ module seg( input clk, input rst_n, input [33:0]tenvalue, output reg [7:0]segdata, output reg [2:0]segcs ); reg[31:0] count; reg[24:0]count1ms; reg[2:0]number; reg clk1ms; parameter sample=2'b00, display=2'b01; //-----------数码管驱动时钟----------- always@(posedge clk or negedge rst_n) begin if (!rst_n)begin count1ms <= 1'd0; clk1ms <= 1'd0; end else if(count1ms >= 25'd50000) // 1ms的计数器 begin clk1ms <= ~clk1ms; count1ms <= 1'd0; end else count1ms <= count1ms + 1'd1; end //-----------数码管译码----------- function [7:0] leddata; input [3:0] datain; begin case(datain) 4'd0: leddata = 8'b11000000; // 0 4'd1: leddata = 8'b11111001; // 1 4'd2: leddata = 8'b10100100; // 2 4'd3: leddata = 8'b10110000; // 3 4'd4: leddata = 8'b10011001; // 4 4'd5: leddata = 8'b10010010; // 5 4'd6: leddata = 8'b10000010; // 6 4'd7: leddata = 8'b11111000; // 7 4'd8: leddata = 8'b10000000; // 8 4'd9: leddata = 8'b10010000; // 9 4'd11: leddata = 8'b01111111; // . default: leddata = 8'b11111111; endcase end endfunction //-----------数码管扫描----------- always@(posedge clk1ms or negedge rst_n) begin if(!rst_n) number <= 3'd0; else if(number == 3'd3) number <= 3'd0; else number <= number + 1; case(number) 3'd0: begin segdata <= leddata(tenvalue % 10); // 个位 segcs <= 3'b101; end 3'd1: begin segdata <= leddata((tenvalue / 10) % 10); // 十位 segcs <= 3'b100; end 3'd2: begin segdata <= leddata((tenvalue / 100) % 10); // 百位 segcs <= 3'b011; end 3'd3: begin segdata<=leddata((tenvalue/1000)%10);//千位 segcs<=3'b010; end default: begin segdata <= 8'b11111111; // 或者其他默认值 segcs <= 3'b111; // 或者其他默认值 end endcase end endmodule

等精度测量法频率测量模块

freq_meter_calc.v
`timescale 1ns/1ns //////////////////////////////////////////////////////////////////////// // Author : EmbedFire // Create Date : 2019/07/10 // Module Name : freq_meter_calc // Project Name : freq_meter // Target Devices: Altera EP4CE10F17C8N // Tool Versions : Quartus 13.0 // Description : 频率计算模块 // // Revision : V1.0 // Additional Comments: // // 实验平台: 野火_征途Pro_FPGA开发板 // 公司 : http://www.embedfire.com // 论坛 : http://www.firebbs.cn // 淘宝 : https://fire-stm32.taobao.com //////////////////////////////////////////////////////////////////////// module freq_meter_calc ( input wire sys_clk , //系统时钟,频率50MHz input wire sys_rst_n , //复位信号,低电平有效 input wire clk_test , //待检测时钟 output reg [33:0] freq //待检测时钟频率 ); //********************************************************************// //****************** Parameter And Internal Signal *******************// //********************************************************************// //parameter define parameter CNT_GATE_S_MAX = 28'd74_999_999 , //软件闸门计数器计数最大值 CNT_RISE_MAX = 28'd12_500_000 ; //软件闸门拉高计数值 parameter CLK_STAND_FREQ = 28'd100_000_000 ; //标准时钟时钟频率 //wire define wire clk_stand ; //标准时钟,频率100MHz wire gate_a_fall_s ; //实际闸门下降沿(标准时钟下) wire gate_a_fall_t ; //实际闸门下降沿(待检测时钟下) //reg define reg [27:0] cnt_gate_s ; //软件闸门计数器 reg gate_s ; //软件闸门 reg gate_a ; //实际闸门 reg gate_a_stand ; //实际闸门打一拍(标准时钟下) reg gate_a_test ; //实际闸门打一拍(待检测时钟下) reg [47:0] cnt_clk_stand ; //标准时钟周期计数器 reg [47:0] cnt_clk_stand_reg ; //实际闸门下标志时钟周期数 reg [47:0] cnt_clk_test ; //待检测时钟周期计数器 reg [47:0] cnt_clk_test_reg ; //实际闸门下待检测时钟周期数 reg calc_flag ; //待检测时钟时钟频率计算标志信号 reg [63:0] freq_reg ; //待检测时钟频率寄存 reg calc_flag_reg ; //待检测时钟频率输出标志信号 //********************************************************************// //***************************** Main Code ****************************// //********************************************************************// //cnt_gate_s:软件闸门计数器 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_gate_s <= 28'd0; else if(cnt_gate_s == CNT_GATE_S_MAX) cnt_gate_s <= 28'd0; else cnt_gate_s <= cnt_gate_s + 1'b1; //gate_s:软件闸门 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) gate_s <= 1'b0; else if((cnt_gate_s>= CNT_RISE_MAX) && (cnt_gate_s <= (CNT_GATE_S_MAX - CNT_RISE_MAX))) gate_s <= 1'b1; else gate_s <= 1'b0; //gate_a:实际闸门 always@(posedge clk_test or negedge sys_rst_n) if(sys_rst_n == 1'b0) gate_a <= 1'b0; else gate_a <= gate_s; //cnt_clk_stand:标准时钟周期计数器,计数实际闸门下标准时钟周期数 always@(posedge clk_stand or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_clk_stand <= 48'd0; else if(gate_a == 1'b0) cnt_clk_stand <= 48'd0; else if(gate_a == 1'b1) cnt_clk_stand <= cnt_clk_stand + 1'b1; //cnt_clk_test:待检测时钟周期计数器,计数实际闸门下待检测时钟周期数 always@(posedge clk_test or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_clk_test <= 48'd0; else if(gate_a == 1'b0) cnt_clk_test <= 48'd0; else if(gate_a == 1'b1) cnt_clk_test <= cnt_clk_test + 1'b1; //gate_a_stand:实际闸门打一拍(标准时钟下) always@(posedge clk_stand or negedge sys_rst_n) if(sys_rst_n == 1'b0) gate_a_stand <= 1'b0; else gate_a_stand <= gate_a; //gate_a_fall_s:实际闸门下降沿(标准时钟下) assign gate_a_fall_s = ((gate_a_stand == 1'b1) && (gate_a == 1'b0)) ? 1'b1 : 1'b0; //cnt_clk_stand_reg:实际闸门下标志时钟周期数 always@(posedge clk_stand or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_clk_stand_reg <= 32'd0; else if(gate_a_fall_s == 1'b1) cnt_clk_stand_reg <= cnt_clk_stand; //gate_a_test:实际闸门打一拍(待检测时钟下) always@(posedge clk_test or negedge sys_rst_n) if(sys_rst_n == 1'b0) gate_a_test <= 1'b0; else gate_a_test <= gate_a; //gate_a_fall_t:实际闸门下降沿(待检测时钟下) assign gate_a_fall_t = ((gate_a_test == 1'b1) && (gate_a == 1'b0)) ? 1'b1 : 1'b0; //cnt_clk_test_reg:实际闸门下待检测时钟周期数 always@(posedge clk_test or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_clk_test_reg <= 32'd0; else if(gate_a_fall_t == 1'b1) cnt_clk_test_reg <= cnt_clk_test; //calc_flag:待检测时钟时钟频率计算标志信号 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) calc_flag <= 1'b0; else if(cnt_gate_s == (CNT_GATE_S_MAX - 1'b1)) calc_flag <= 1'b1; else calc_flag <= 1'b0; //freq_reg:待检测时钟信号时钟频率寄存 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) freq_reg <= 64'd0; else if(calc_flag == 1'b1) freq_reg <= (CLK_STAND_FREQ * cnt_clk_test_reg / cnt_clk_stand_reg); //calc_flag_reg:待检测时钟频率输出标志信号 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) calc_flag_reg <= 1'b0; else calc_flag_reg <= calc_flag; //freq:待检测时钟信号时钟频率 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) freq <= 34'd0; else if(calc_flag_reg == 1'b1) freq <= freq_reg[33:0]; //********************************************************************// //*************************** Instantiation **************************// //********************************************************************// //---------- clk_gen_inst ---------- clk_gen clk_gen_inst ( .areset (~sys_rst_n ), .inclk0 (sys_clk ), .c0 (clk_stand ) ); endmodule

本站由 John Doe 使用 Stellar 1.28.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本"页面"访问 次 | 👀总访问 次 | 🥷总访客