У меня вопрос, связанный с непрерывным усреднением значения АЦП. Подход, который я использовал, заключается в непрерывном усреднении примеров из 256 образцов. Значение «adc_a_out» (показанное в приведенном ниже коде), которое я получаю в своем графическом интерфейсе, увеличивается медленно. Например, если я ожидаю значение 100 мА, мой графический интерфейс показывает 4 мА, 8 мА, 15 мА, ......, а затем, наконец, через 2 минуты я получаю стабильное значение 100 мА. Я хочу видеть 100 мА непосредственно в моем графическом интерфейсе из «adc_a_out» вместо увеличения значений и стабилизации через некоторое время. Другой вопрос, Можно ли как-то сделать этот процесс быстрым, чтобы не ждать 3 минуты получения стабильных 100 мА от adc_a_out. Тактовый щелчок в цифровом дизайне ниже составляет 20 МГц. Тактовая частота приема значений АЦП на плате FPGA составляет 15 кГц.
--adc_top_file.vhd
entity adc_block_1 is
port (
clk : in std_logic;
reset : in std_logic;
data_in : in std_logic_vector (31 downto 0);
req : in std_logic;
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
slv_value1 : out std_logic_vector (11 downto 0);
slv_value2 : out std_logic_vector (11 downto 0);
);
end adc_block_1;
architecture adc_top_block of adc_block_1 is
component adc is
port (
clk : in std_logic;
reset : in std_logic;
data_in : in std_logic_vector (31 downto 0);
req : in std_logic;
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
adc_a_1_temp: out signed(11 downto 0);
adc_b_1_temp: out signed(11 downto 0);
slv_value1 : out std_logic_vector (11 downto 0);
slv_value2 : out std_logic_vector (11 downto 0);
);
end component;
component use_moving_average is
port (
clock: in std_logic;
reset: in std_logic;
channel_1_sample: in signed(11 downto 0);
channel data_in : in std_logic_vector (31 downto 0);
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
adc_a_1_temp: out signed(11 downto 0);
adc_b_1_temp: out signed(11 downto 0);
load : out std_logic;
process (clk, reset)
begin
if (reset = '1') then
state<=idle;
adc_out1=0;
adc_out2 <= 0;
elsif(rising_edge(clk)) then
case state is
when idle =>
if req='1' then
state= out_1;
end if;
when out_1 =>
if done='1' then
data_out <= addr0 & bits;
adc_a_1 <= data_in(11 downto 0);
adc_a_1_temp <= signed(adc_a_1);
state <= out_2;
endif;
when out_2 =>
if done='1' then
adc_b_1 <= data_in(11 downto 0);
adc_b_1_temp <= signed(adc_b_1);
state <= done_st;
when done_st =>
ack <='1';
--load <='1';
state <= idle;
when others =>
state <= idle;
end case;
end if;
end process;
load: process (clk, reset)
begin
if (reset = '1') then
load <= '0';
elsif (rising_edge(clk)) then
max_cnt <= 5000000;
load <= '0';
else
max_cnt <= max_cnt -1;
load <= '1';
end if;
end process load;
sample: in signed(11 downto 0);
channel_1_average: inout signed(11 downto 0);
channel data_in : in std_logic_vector (31 downto 0);
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
adc_a_1_temp: out signed(11 downto 0);
adc_b_1_temp: out signed(11 downto 0);
load : out std_logic;
process (clk, reset)
begin
if (reset = '1') then
state<=idle;
adc_out1=0;
adc_out2 <= 0;
elsif(rising_edge(clk)) then
case state is
when idle =>
if req='1' then
state= out_1;
end if;
when out_1 =>
if done='1' then
data_out <= addr0 & bits;
adc_a_1 <= data_in(11 downto 0);
adc_a_1_temp <= signed(adc_a_1);
state <= out_2;
endif;
when out_2 =>
if done='1' then
adc_b_1 <= data_in(11 downto 0);
adc_b_1_temp <= signed(adc_b_1);
state <= done_st;
when done_st =>
ack <='1';
--load <='1';
state <= idle;
when others =>
state <= idle;
end case;
end if;
end process;
load: process (clk, reset)
begin
if (reset = '1') then
load <= '0';
elsif (rising_edge(clk)) then
max_cnt <= 5000000;
load <= '0';
else
max_cnt <= max_cnt -1;
load <= '1';
end if;
end process load;
average: inout signed(11 downto 0);
slv_value1 : out std_logic_vector (11 downto 0);
slv_value2 : out std_logic_vector (11 downto 0)
);
end component;
signal adc_a_1_temp : std_logic_vector(11 downto 0);
signal adc_b_1_temp : std_logic_vector(11 downto 0);
signal adc_a_1_out : std_logic_vector(11 downto 0);
signal adc_b_1_out : std_logic_vector(11 downto 0);
begin
inst_adc : adc
port map (
clk => clk,
reset => reset,
req => adc_req,
adc_a_1 => adc_a_1_temp,
adc_b_1 => adc_b_1_temp,
adc_a_1_temp => adc_a_1_temp,
adc_b_1_temp => adc_b_1_temp
);
inst_moving_average : use_moving_average
port map (
clock => clk,
reset => reset,
channel_1_sample => adc_a_1_temp,
channel data_in : in std_logic_vector (31 downto 0);
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
adc_a_1_temp: out signed(11 downto 0);
adc_b_1_temp: out signed(11 downto 0);
load : out std_logic;
process (clk, reset)
begin
if (reset = '1') then
state<=idle;
adc_out1=0;
adc_out2 <= 0;
elsif(rising_edge(clk)) then
case state is
when idle =>
if req='1' then
state= out_1;
end if;
when out_1 =>
if done='1' then
data_out <= addr0 & bits;
adc_a_1 <= data_in(11 downto 0);
adc_a_1_temp <= signed(adc_a_1);
state <= out_2;
endif;
when out_2 =>
if done='1' then
adc_b_1 <= data_in(11 downto 0);
adc_b_1_temp <= signed(adc_b_1);
state <= done_st;
when done_st =>
ack <='1';
--load <='1';
state <= idle;
when others =>
state <= idle;
end case;
end if;
end process;
load: process (clk, reset)
begin
if (reset = '1') then
load <= '0';
elsif (rising_edge(clk)) then
max_cnt <= 5000000;
load <= '0';
else
max_cnt <= max_cnt -1;
load <= '1';
end if;
end process load;
sample => adc_b_1_temp,
channel_1_average => adc_a_1_out,
channel data_in : in std_logic_vector (31 downto 0);
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
adc_a_1_temp: out signed(11 downto 0);
adc_b_1_temp: out signed(11 downto 0);
load : out std_logic;
process (clk, reset)
begin
if (reset = '1') then
state<=idle;
adc_out1=0;
adc_out2 <= 0;
elsif(rising_edge(clk)) then
case state is
when idle =>
if req='1' then
state= out_1;
end if;
when out_1 =>
if done='1' then
data_out <= addr0 & bits;
adc_a_1 <= data_in(11 downto 0);
adc_a_1_temp <= signed(adc_a_1);
state <= out_2;
endif;
when out_2 =>
if done='1' then
adc_b_1 <= data_in(11 downto 0);
adc_b_1_temp <= signed(adc_b_1);
state <= done_st;
when done_st =>
ack <='1';
--load <='1';
state <= idle;
when others =>
state <= idle;
end case;
end if;
end process;
load: process (clk, reset)
begin
if (reset = '1') then
load <= '0';
elsif (rising_edge(clk)) then
max_cnt <= 5000000;
load <= '0';
else
max_cnt <= max_cnt -1;
load <= '1';
end if;
end process load;
average => adc_b_1_out,
slv_value1 => slv_value1,
slv_value2 => slv_value2
);
-- файл adc.vhd находится ниже:
data_in : in std_logic_vector (31 downto 0);
adc_a_1 : inout std_logic_vector (11 downto 0);
adc_b_1 : inout std_logic_vector (11 downto 0);
adc_a_1_temp: out signed(11 downto 0);
adc_b_1_temp: out signed(11 downto 0);
load : out std_logic;
process (clk, reset)
begin
if (reset = '1') then
state<=idle;
adc_out1=0;
adc_out2 <= 0;
elsif(rising_edge(clk)) then
case state is
when idle =>
if req='1' then
state= out_1;
end if;
when out_1 =>
if done='1' then
data_out <= addr0 & bits;
adc_a_1 <= data_in(11 downto 0);
adc_a_1_temp <= signed(adc_a_1);
state <= out_2;
endif;
when out_2 =>
if done='1' then
adc_b_1 <= data_in(11 downto 0);
adc_b_1_temp <= signed(adc_b_1);
state <= done_st;
when done_st =>
ack <='1';
--load <='1';
state <= idle;
when others =>
state <= idle;
end case;
end if;
end process;
load: process (clk, reset)
begin
if (reset = '1') then
load <= '0';
elsif (rising_edge(clk)) then
max_cnt <= 5000000;
load <= '0';
else
max_cnt <= max_cnt -1;
load <= '1';
end if;
end process load;
Ваш код изменен следующим образом:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity use_moving_average is
port (
clock: in std_logic;
reset: in std_logic;
channel_1_sample: in signed(11 downto 0);
channel_2_sample: in signed(11 downto 0);
channel_1_average: inout signed(11 downto 0);
channel_2_average: inout signed(11 downto 0);
slv_value1 : out std_logic_vector (11 downto 0);
slv_value2 : out std_logic_vector (11 downto 0)
);
end;
architecture rtl of use_moving_average is
signal average_1, average_2: integer;
begin
channel_1: entity work.moving_average
port map(
sample => to_integer(channel_1_sample),
average => average_1,
clock => clock,
reset => reset
);
channel_2: entity work.moving_average
port map(
sample => channel_2_sample,
average => average_2,
clock => clock,
reset => reset
);
channel_1_average <= to_signed(average_1, 12);
slv_value1 <= std_logic_vector(channel_1_average);
channel_2_average <= to_signed(average_2, 12);
slv_value2 <= std_logic_vector(channel_2_average);
end;
Окончательный вывод, который я просматриваю в своем графическом интерфейсе, - это «slv_value1» и «slv_value2».
Спасибо!