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

2019-07-15 22:43发布

代码 如下   在高电平计数到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

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
ji****ex
1楼-- · 2019-07-15 23:00
dout <= 1+1000* time_h/time_a;
好像这里有问题,400M时钟在86mS里计数0x20ce700,乘1000之后=0x8 0266 5800,超过了32位吧?是不是溢出了?
另外,好像极限测量时间不是86mS,好像超过10.7mS乘法就溢出了,但是编译时可能结合了除法的优化,使得实际的测量乘法的上限到达了0x7 ffff ffff。请改一里再试验一下,祝好运! 最佳答案
ji****ex
2楼-- · 2019-07-16 02:06
先把乘1000改成乘100试验一下,如果上限变了,基本就确定是溢出了。
songsiming27
3楼-- · 2019-07-16 02:13
ji****ex 发表于 2016-5-17 23:09
dout

看了回复,觉得就是这里的错误   谢谢啦
songsiming27
4楼-- · 2019-07-16 02:32
现在的问题是我把1000放在最后面乘的话数据是0  这该怎么改呢?
jiaojiex
5楼-- · 2019-07-16 05:24
 精彩回答 2  元偷偷看……
songsiming27
6楼-- · 2019-07-16 07:32
jiaojiex 发表于 2016-5-20 23:42
"1000放在最后面乘的话数据是0"是因为先算了除法,这个除法是整数除法,没小数部分,所以结果得0.
可能有两个办法可以解决:
1、因为乘1000改小一些可以提高上限,所以可以用分段的方法,对不同测量区间乘以不同的系数。

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

一周热门 更多>