Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

signal power estimation

Hello guys..

I'm trying to implement a block that evaluates the signal rms value along n samples.

So, using the std definition one must do (x_k is a complex number so I have to take in account |x_k|):

http://upload.wikimedia.org/math/0/1/4/014a453df92ed77eca97b228f0624d9f.png

The simplier way I have in mind is to use an accumulator. By the way it will indroduce some overflow issues. There is a good way in doing this ??

Thank you !

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you kaz.. I'm on it..

    I've written the following code:

    
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE IEEE.std_logic_unsigned.all;
    ENTITY rms_estimator IS
        GENERIC (ACCBIT : INTEGER:=10);
        PORT( squared_abs : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
                clk , clr : IN STD_LOGIC;
                squared_rms: OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
                ready : out STD_LOGIC;
    END ENTITY rms_estimator;
    ARCHITECTURE logic OF rms_estimator IS
    signal sum : STD_LOGIC_VECTOR(ACCBIT+31 downto 0):=(OTHERS =>'0');
    signal i : STD_LOGIC_VECTOR(ACCBIT downto 0):=(OTHERS =>'0');
    BEGIN
    PROCESS(clk,clr)
        
       BEGIN
            IF(clr = '1') THEN
                squared_rms<=(OTHERS =>'0');
                sum<=(OTHERS =>'0');
                ready<='0';
                i<=(OTHERS =>'0');
            ELSIF rising_edge(clk) THEN
                if (i=2**ACCBIT) then
                   squared_rms<=std_logic_vector(sum(ACCBIT+31 downto ACCBIT));
                   ready<='1';
                else
                    sum<=  sum + unsigned(pad & squared_abs);
                    i<=i+1;
                    ready<='0';
                    squared_rms<=(others=>'0');
                end if;
            END IF;
        END PROCESS;
    END ARCHITECTURE logic;

    by the way the squared_rms is always at 'X' after the ready bit is set to '1'.. Any suggestions ?? I'm really stucked...

    Thank you for your time!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    some suggestions(not compiled)

    
    ARCHITECTURE logic OF rms_estimator IS 
    signal sum : unsigned(ACCBIT+31 downto 0):=(OTHERS =>'0'); 
    signal i : unsigned(ACCBIT downto 0):=(OTHERS =>'0');  
    BEGIN 
    PROCESS(clk,clr) 
    BEGIN 
    IF(clr = '1') THEN 
        squared_rms <= (OTHERS =>'0');             
        sum <= (OTHERS =>'0');
        ready <= '0'; 
        i < =(OTHERS =>'0'); 
    ELSIF rising_edge(clk) THEN 
        if (i=2**ACCBIT - 1) then
             sum <= (others => '0');                
             squared_rms<=std_logic_vector(sum(ACCBIT+31 downto ACCBIT));                
             ready<='1';
             i <= (others => '0');             
         else                
            sum<=  sum + unsigned(pad & squared_abs); -- what is pad? '0'?                
            i<=i+1;                 
            ready<='0';                 
            --squared_rms<=(others=>'0'); -- you may keep it latched            
         end if;         
    END IF;     
    END PROCESS;
     END ARCHITECTURE logic;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you kaz..

    the 'pad' was not intended to be there it was written down in a previus attempt.

    I have not updated the 'i' signal after it equals 2**ACCBIT because for testing pourpose I want to stop the sum when the ready bit is set.

    By the way I always have XXXX... as output when the ready bit is set... mumble mumble..

    It seems that the problem is in the recursion..

    If i set:

    sum<=32767+sum ==> the rms is 32767 as expected
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    try correct the width of squared_rms (should be less 10 bits).

    edit: ignore this note as it is 32 bits so is abs

    change sum type to unsigned
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Dear kaz..

    What I see is that at reset time:

    sum=0;

    Then at the first sum:

    sum<=sum+unsigned(squared_abs) --squared_abs=2147483647 loaded from a .dat file

    The result is XXXXXX and it mantains its value until the ready bit is set and de-set. After the de-setting it starts summing correctly from 0.

    Thank you !
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've found the bug.. In the testbench i was not restting the input. Now it seems to work correctly. Thank you for the help kaz. You're a real guru !

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello guys..

    Now I'm working with RMS power estimation again.. I have two complex signals: sig1 and sig2.

    I measure the RMS of sig1 and sig2 with a vhdl block and then via software I calculate: [(float) RMS(sig1)] / [(float) RMS(sig2)] with sig1>sig2.

    I want that RMS(sig1) ~= RMS(sig2). So I tried to multiply sig2 with a 16-int-constant related to [(float) RMS(sig1)] / [(float) RMS(sig2)] and then take the 16-MSB after that multiplication. By the way I think I'm still missing something because I see funny results..

    Any suggestions ?

    Thank you! have a nice day !