2

I have a question related to conversion from numeric_std to std_logic_vector. I am using moving average filter code that I saw online and filtering my ADC values to stable the values.

The filter package code is:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package filterpack is
  subtype number is unsigned(27 downto 0);
  type numbers is array(natural range <>) of number;
  function slv_to_num(signal slv: in std_logic_vector) return number;
  procedure MAF_filter(
    signal x: in    number;
    signal h: inout numbers;
    signal y: out   number
  );
end filterpack;

package body filterpack is

function slv_to_num(signal slv: in std_logic_vector) return number is
  variable x: number := (others => '0');
begin
  for i in slv'range loop
    if slv(i) = '1' then
      x(i+4) := '1';
    end if;
  end loop;
  return x;
end function slv_to_num;

procedure MAF_filter(
    signal x: in    number;
    signal h: inout numbers;
    signal y: out   number
  ) is
begin
  h(0) <= x + h(1);       -- h[n] = x[n] + h[n-1]
  y <= h(0) - h(h'high);  -- y[n] = h[n] - h[n-M]
end MAF_filter;

end package body filterpack;

In my top level file, I call the MAF_filter procedure.

Asign_x: x <= slv_to_num(adc_dat);
Filter:  MAF_filter(x,h,y);

The adc_dat is defined as:

adc_dat : out std_logic_vector (23 downto 0);

I want to convert the output of the MAF_Filter to std_logic_vector (23 downto 0). Can anyone tell how can I convert filter output 'y' to 'std_logic_vector'?

Many Thanks!

2 Answers 2

1

What do you want to do with the 4 extra bits? Your type number has 28 bits, but your signal adc_dat has only 24.

If it's ok to discard them, you could use:

adc_dat <= std_logic_vector(y(adc_dat'range));

Also, is there a reason not to write your function slv_to_num as shown below?

function slv_to_num(signal slv: in std_logic_vector) return number is
begin
  return number(slv & "0000");
end function slv_to_num;
Sign up to request clarification or add additional context in comments.

2 Comments

I used the already made code for MAF. I have to use 4 extra bits because of the function slv_to_num definition.
I edited the answer with a suggestion for your function slv_to_num
0

The conversion has to solve 2 problems : the type difference you noted, and the fact that the two words are different sizes.

The type difference is easy : std_logic_vector (y) will give you the correct type. Because the two types are related types, this is just a cast.

The size difference ... only you have the knowledge to do that.

adc_dat <= std_logic_vector(y(23 downto 0)) will give you the LSBs of Y - i.e. the value of Y itself, but can overflow. Or as Rick says, adc_dat <= std_logic_vector(y(adc_dat'range)); which is usually better, but I wanted to expose the details.

adc_dat <= std_logic_vector(y(27 downto 4)) cannot overflow, but actually gives you y/16.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.