微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > FPGA占空比测量 帮忙误差解决

FPGA占空比测量 帮忙误差解决

时间:10-02 整理:3721RD 点击:
代码 如下   在高电平计数到86ms以上时就会出现很大的误差  仿真也没问题  是什么原因呢?
module dutycycle(
    clk         ,
    rst_n       ,
    clk_400M    ,
    signal      ,
    en_d        ,
    flag_d      ,
    dout      
    );
    //输入信号定义
    input           clk      ;
    input           rst_n    ;
    input           clk_400M ;
    input           signal   ;
    input           en_d     ;
    //输出信号定义
    output[31:0]    dout     ;
    output          flag_d   ;
    //输出信号reg定义
    reg   [31:0]   dout      ;
    reg            flag_d    ;
        reg    [31:0]   time_h    ;
    reg   [31:0]   time_a    ;
    //中间信号定义
    reg            signal_ff0;
    reg            signal_ff1;
    reg            signal_ff2;
        reg   [31:0]   time_h_buf;
        reg   [31:0]   time_a_buf;
    reg   [2:0]    state     ;
        wire           jump_p1   ;
    wire           jump_p2   ;
        wire           jump_n    ;
    assign    jump_p1 = signal_ff0 && ~signal_ff1;    //第一个上升沿
    assign    jump_p2 = signal_ff1 && ~signal_ff2;    //第二个上升沿
    assign    jump_n  = ~signal_ff0 && signal_ff1;    //第一个下降沿
         
    always@(posedge clk_400M or negedge rst_n)begin
        if(rst_n==1'b0)begin
            signal_ff0 <= 0;
            signal_ff1 <= 0;
            signal_ff2 <= 0;
        end
        else begin
            signal_ff0 <= signal;
            signal_ff1 <= signal_ff0;
            signal_ff2 <= signal_ff1;
        end
    end
         
    //占空比测量
    always  @(posedge clk_400M or negedge rst_n)begin
        if(rst_n==1'b0)begin
            state <= 0;
        end
        else if(jump_p1&&state==0&&en_d)begin
            state <= 1;
        end
        else if(jump_n&&state==1)begin
            state <= 2;
        end
                  else if(jump_p2&&state==2)begin
            state <= 3;
        end
            else if(state==3)begin
            state <= 4;        
        end
        else if (state==4)begin
            state <= 0;
        end
    end
    always  @(posedge clk_400M or negedge rst_n)begin
        if(rst_n==1'b0)begin
            dout <= 32'd0;
            flag_d <= 0;
            time_h <= 32'd0;
            time_a <= 32'd0;
            time_h_buf <= 32'd0;
            time_a_buf <= 32'd0;
        end
        else begin
            case(state)
                3'd1:begin
                    time_h_buf <= time_h_buf + 1'b1;
                    time_a_buf <= time_a_buf + 1'b1;
                end
                3'd2:begin
                    time_h_buf <= time_h_buf;
                    time_a_buf <= time_a_buf + 1'b1;
                end  
                3'd3:begin
                    time_h <= time_h_buf;
                    time_a <= time_a_buf;
                end
                3'd4:begin
                    dout <= 1+1000* time_h/time_a;
                    flag_d <= 1'd1;
                end
                default:begin
                    dout <= 32'd0;
                    flag_d <= 0;
                    //time_h <= 32'd0;
                    //time_a <= 32'd0;
                    time_h_buf <= 32'd0;
                    time_a_buf <= 32'd0;
                end
            endcase
        end
    end
    endmodule

dout <= 1+1000* time_h/time_a;
好像这里有问题,400M时钟在86mS里计数0x20ce700,乘1000之后=0x8 0266 5800,超过了32位吧?是不是溢出了?
另外,好像极限测量时间不是86mS,好像超过10.7mS乘法就溢出了,但是编译时可能结合了除法的优化,使得实际的测量乘法的上限到达了0x7 ffff ffff。请改一里再试验一下,祝好运!

先把乘1000改成乘100试验一下,如果上限变了,基本就确定是溢出了。

看了回复,觉得就是这里的错误   谢谢啦

现在的问题是我把1000放在最后面乘的话数据是0  这该怎么改呢?

"1000放在最后面乘的话数据是0"是因为先算了除法,这个除法是整数除法,没小数部分,所以结果得0.
可能有两个办法可以解决:
1、因为乘1000改小一些可以提高上限,所以可以用分段的方法,对不同测量区间乘以不同的系数。
2、为了不损失精度,需要提高time_a 和time_h 的位数,不知您的编译器是否直接支持64位乘除?如果不支持,就得分解成为多次32位乘除法。会比较麻烦。 如果换成浮点运算,只是理论上可行,但是我没用逻辑做过。FPGA中用CPU软核来计算这个64位乘除法,或浮点乘除法是可行的。

谢谢你为我解决了这个问题

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

网站地图

Top