• 测量占空比


    最近尝试了很多方法测量占空比,虽然说原理简单,但是测量的时候误差还是挺大的,凡是没呢么容易,

    最后终于实现了1HZ-5M 占空比的测量,精度小于%0.1

    另外发现了一个问题,fpga一条语句如果很复杂的话,可能会出现问题。

    例如 assign  duty_altera = pinlv << 1 + pinlv;也就是pinlv_altera 是频率的三倍,在sigtab仿真时出错了,如果把这两条语句分开写就没毛病了。

    这说明在200M高速频率下,这样写法不太好,跑不了高速。

    程序思路:

    设定一个1S钟的闸门,在闸门有效期间测量高电平持续时间和低电平持续时间,需要注意的是:

    在测量时间时需要以边沿做为开始计数的标志,否则程序容易崩溃。然而实际测量出来,还是有误差的,经过测量多组数据发现:高电平测量的时间所记录的个数比实际上少记录了2*pinlv个,而低电平恰恰相反。经过补偿,满足题目的要求。

    module    duty(
            //system    interface
            input                clk,
            input                rst_n,
            //sig        interface
            input                sig_in,
            //pinlv        interface
            input        [31:0]    pinlv,
            //user        interface
            output    reg    [15:0]    duty,
            output    reg    [31:0]    cnt_high,
            output    reg    [31:0]    cnt_low,
            output                high_pulse,
            output                low_pulse,
            output        [31:0]    duty_alter
    );
    
    //buffer
    reg        sig_in_buffer;
    reg        sig_in_buffer1;
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
            sig_in_buffer  <= 0;
            sig_in_buffer1 <= 0;
        end
        else
        begin
            sig_in_buffer  <= sig_in;
            sig_in_buffer1 <= sig_in_buffer;
        end
    end
    assign        high_pulse =  (sig_in_buffer == 1 && sig_in_buffer1 == 0) ? 1 : 0;
    assign        low_pulse  =  (sig_in_buffer == 0 && sig_in_buffer1 == 1) ? 1 : 0;
    //parameter        CNT_1S = 32'd199_9;
    parameter        CNT_1S = 32'd199_999_999;
    reg        [31:0]    cnt_1s;
    reg                fgate;
    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            cnt_1s <= 0;
        else if(cnt_1s >= CNT_1S)
            cnt_1s <= 0;
        else 
            cnt_1s <= cnt_1s + 1;
    end
    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            fgate <= 0;
        else if(cnt_1s == CNT_1S)
            fgate <= ~fgate;
        else
            fgate <= fgate;
    end
    
    
    reg        fstart;
    always @(posedge sig_in_buffer1 or negedge rst_n)
    begin
        if(!rst_n)
            fstart <= 0;
        else if(fgate)
            fstart <= 1;
        else
            fstart <= 0;
    end
    reg        [2:0]        state_high;
    reg        [2:0]        state_low;
    //cnt
    reg        [31:0]        cnt_high_temp;
    reg        [31:0]        cnt_low_temp;
    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            state_high <= 0;
        else
        case(state_high)
        2'd0 :
        begin
            if(high_pulse)
                state_high <= 2'd1;
            else
                state_high <= 2'd0;
        end
        
        2'd1 :
        begin
            if(low_pulse)
                state_high <= 2'd0;
            else
                state_high <= 2'd1;
        end
        
        default : ;
        endcase
    end
    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            state_low <= 0;
        else
        case(state_low)
        2'd0 :
        begin
            if(low_pulse)
                state_low <= 2'd1;
            else
                state_low <= 2'd0;
        end
        
        2'd1 :
        begin
            if(high_pulse)
                state_low <= 2'd0;
            else
                state_low <= 2'd1;
        end
    
        default : ;
        endcase
    end
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            cnt_high_temp <= 0;
        else if(fstart)
        begin
            if(state_high == 1)
                cnt_high_temp <= cnt_high_temp + 1;
            else
                cnt_high_temp <= cnt_high_temp;
        end
        else
            cnt_high_temp <= 0;    
    end
    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            cnt_low_temp <= 0;
        else if(fstart)
        begin
            if(state_low == 1)
                cnt_low_temp <= cnt_low_temp + 1;
            else
                cnt_low_temp <= cnt_low_temp;
        end
        else
            cnt_low_temp <= 0;    
    end
    wire    [31:0]    pinlv1;
    assign    pinlv1     = pinlv << 1;
    assign    duty_alter =  pinlv << 1;
    
    always @(negedge fstart or negedge rst_n)
    begin
        if(!rst_n)
        begin
            cnt_high <= 0;
            cnt_low <= 0;
        end
        else
        begin
            cnt_high <= cnt_high_temp + duty_alter ;
            cnt_low  <= cnt_low_temp  - duty_alter ; 
        end
    end
    
    
    
    
    
    
    endmodule
  • 相关阅读:
    jmeter分布式配置
    APP自动化测试获取包名的两种方法
    Monkey自动化测试命令
    jmeter之http请求用csv读取中文乱码
    jmeter断言之响应code:200
    使用 form 和 iframe 实现图片上传回显
    sublime3 破解
    在cmd下面执行.py文件时提示ModuleNotFoundError 但是 IDE 不报错
    windows 开启 nginx 监听80 端口 以及 禁用 http 服务后,无法重启 HTTP 服务,提示 系统错误 123,文件目录、卷标出错
    python打包exe
  • 原文地址:https://www.cnblogs.com/bixiaopengblog/p/6915653.html
Copyright © 2020-2023  润新知