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

2019-07-15 21:31发布

大二在读学生,在准备电赛,最近在做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


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
Sam`star
1楼-- · 2019-07-16 02:46
学习FPGA方面的东西才一周,可能有一些对于它的理解有些问题的地方,希望各位大手发现问题能够麻烦指出一下,非常感谢
yan~yan
2楼-- · 2019-07-16 04:06
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 没有写全

评分

参与人数 1积分 +5 收起 理由 ElecFans王岑 + 5

查看全部评分

一周热门 更多>