zoukankan      html  css  js  c++  java
  • 测量占空比

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

    最后终于实现了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
  • 相关阅读:
    移动端开发
    webpack2系列step2--CSS
    webpack2系列step1--HTML
    react+redux官方实例TODO从最简单的入门(6)-- 完结
    react+redux官方实例TODO从最简单的入门(5)-- 查
    react+redux官方实例TODO从最简单的入门(4)-- 改
    react+redux官方实例TODO从最简单的入门(3)-- 删
    react+redux官方实例TODO从最简单的入门(1)-- 前言
    react+redux官方实例TODO从最简单的入门(2)-- 增
    Git 标签管理
  • 原文地址:https://www.cnblogs.com/bixiaopengblog/p/6915653.html
Copyright © 2011-2022 走看看