微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > FPGA Verilog写的一个数字频率计有一点问题

FPGA Verilog写的一个数字频率计有一点问题

时间:10-02 整理:3721RD 点击:
大二在读学生,在准备电赛,最近在做15年的数字频率计题目,遇到了一点问题
用的是黑金的Cyclone IV开发板
一共有两个功能,频率测量和占空比测量,频率测量的部分很奇怪,计数部分记到的数字正好是频率的两倍(应该正好等于频率的)。 占空比测量部分返回值直接就是乱的。
`timescale 1ns / 1ps
module measure_f (
                                                clk,                 // 开发板上输入时钟: 50Mhz
                                                rst_n,         // 开发板上输入复位按键
                                                SI_OUT,         // 数据输出
                                                SI_IN,        // 信号输入
                                                GO,                //        单片机通信信号
                                                counter,  //        闸门信号
                                                clk_200        //倍频后200M时钟
                                                //clk_400 //倍频后400M时钟
                                                );
                                               
//=====================================================
// 引脚声明
//=====================================================
input clk;
input rst_n;
input SI_IN;
input GO;
output clk_200;
//output clk_400;
output counter;
output [63:0] SI_OUT;
//寄存器定义
reg [31:0] timer = 0;//计时寄存器
reg [31:0] timer_T = 0;//占空比计时寄存器
reg [31:0] T = 0;//记录占空比
reg [63:0] SI_OUT = 0;//信号输出寄存器
reg [31:0] measure_1 = 0;//计数寄存器
reg [31:0] measure_2 = 0;//中转用寄存器
reg[2:0] delay1;//抓边沿用
reg[2:0] delay2;//抓边沿用
reg counter = 0;//闸门
//===================================================
// 抓取边沿
//===================================================
always @ ( posedge clk_200 or negedge rst_n )
  if( !rst_n )
     delay1 <= 0;
  else
     delay1 <= { delay1[1:0], SI_IN};
// SI_IN是原信号
wire pos_SI = delay1[1] && ( ~delay1[2] );       // 原信号上升沿位置处产生的pulse信号
wire neg_SI = ( ~delay1[1] ) && delay1[2];      // 原信号下降沿位置处产生的pulse信号
always @ ( posedge clk_200 or negedge rst_n )
  if( !rst_n )
     delay2 <= 0;
  else
     delay2 <= { delay2[1:0], GO} ;
// GO是原信号
wire pos_GO = delay2[1] && ( ~delay2[2] );       // 原信号上升沿位置处产生的pulse信号
wire neg_GO = ( ~delay2[1] ) && delay2[2];      // 原信号下降沿位置处产生的pulse信号
//===================================================
// 闸门时间:1S
//===================================================
always @(posedge clk_200 or negedge rst_n)
begin
        if (~rst_n) //复位信号低有效
        begin
                timer <= 0; //计数器清零
                counter <= 0;
               
        end
       
        else if (timer == 32'd199_999_999) //200MHz,1 秒计数(200M-1=399_999_999)
        begin
                measure_2 <= measure_1;//将计数值装入中转用寄存器       
                T <= timer_T;//将占空比数据装入占空比中转用寄存器
                timer <= 0; //计数器计到 1 秒,计数器清零
                counter <= ~counter; //闸门取反
        end
       
        else
        timer <= timer + 1'b1; //计数器加 1
       
end
//=====================================================
// 计数器_1 记录脉冲
//=====================================================
always @(posedge clk_200 or negedge rst_n)
begin
        if (~rst_n) //复位信号低有效
                measure_1 <= 0;
               
        else if (counter == 1 && pos_SI)
                measure_1 <= measure_1 + 1'b1;//闸门为开启时计数
       
        else if(counter == 0)
                measure_1 <=0;               
end
//=====================================================
// 计数器_2 通信调整
//=====================================================
always @(posedge clk_200 or negedge rst_n)
begin       
        if (~rst_n) //赋初值
                SI_OUT <= 0;
       
        else if(counter == 0)
        begin       
                   SI_OUT[31:0] <= measure_2;
                SI_OUT[63:32] <= T;
        end
       
        else if (counter == 1 && pos_GO)//匝门开启时发送数据
                begin       
                                SI_OUT <= SI_OUT << 1;                               
                end       
               
end
//=====================================================
// 占空比测量
//=====================================================
always @(posedge clk_200 or negedge rst_n)
begin
        if (~rst_n) //赋初值
                timer_T <= 0;
       
        else if(SI_IN && counter == 1)
                timer_T <= timer_T + 1'b1;
               
        else if (counter == 0)
                timer_T <= 0;
               
end
//=====================================================
// 例化PLL
//=====================================================
pll pll_inst
        (// Clock in ports
                .inclk0(clk), // IN 50Mhz
                // Clock out ports
                .c0(clk_200), // OUT200Mhz
                //.c1(clk_400),
                // Status and control signals
                .areset(~rst_n),// IN
                .locked(locked)
         );
endmodule

学习FPGA方面的东西才一周,可能有一些对于它的理解有些问题的地方,希望各位大手发现问题能够麻烦指出一下,非常感谢

always @(posedge clk_200 or negedge rst_n)
begin
        if (~rst_n) //赋初值
                timer_T <= 0;
        
        else if(SI_IN && counter == 1)
                timer_T <= timer_T + 1'b1;
               
        else if (counter == 0)
                timer_T <= 0;
               
end、
像是有问题;从你的代码上看,在某1秒内,counter为高电平,输入信号高电平时,timer_T 计数,那如果输入信号低电平counter为高电平呢?if else 没有写全

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top