使用VHDL平均12位adc值
我有一个关于ADC值连续平均的问题。我使用的方法是对示例256个样本进行连续平均。我在GUI上接收到的“adc_a_out”值(如下代码所示)缓慢递增。例如,如果我期望值为100mA,我的GUI显示4mA、8mA、15mA,。。。。。。2分钟后,我得到了稳定的100mA值。我想直接从“adc_a_out”在我的GUI上看到100mA,而不是增量值,并在一段时间后稳定下来。另一个问题是,我是否可以加快这个过程,这样我就不必等待3分钟从adc_a_out接收稳定的100 mA。以下数字设计中的时钟“clk”为20 MHz。FPGA板上接收ADC值的时钟为15 KHz使用VHDL平均12位adc值,vhdl,fpga,xilinx,hdl,Vhdl,Fpga,Xilinx,Hdl,我有一个关于ADC值连续平均的问题。我使用的方法是对示例256个样本进行连续平均。我在GUI上接收到的“adc_a_out”值(如下代码所示)缓慢递增。例如,如果我期望值为100mA,我的GUI显示4mA、8mA、15mA,。。。。。。2分钟后,我得到了稳定的100mA值。我想直接从“adc_a_out”在我的GUI上看到100mA,而不是增量值,并在一段时间后稳定下来。另一个问题是,我是否可以加快这个过程,这样我就不必等待3分钟从adc_a_out接收稳定的100 mA。以下数字设计中的时钟“
--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_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 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_2_sample => adc_b_1_temp,
channel_1_average => adc_a_1_out,
channel_2_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;
data\u in:标准逻辑向量(31向下至0);
adc_a_1:输入输出标准逻辑_向量(11向下至0);
adc_b_1:输入输出标准逻辑_向量(11向下至0);
adc_a_1_temp:out signed(11下降到0);
adc_b_1_temp:签出(11下降到0);
加载:输出标准逻辑;
过程(时钟、复位)
开始
如果(重置='1'),则
状态
如果完成class='1',则
数据输出如何:在重置时(或者如果需要,在任何其他时间),将data\u in
值分配给stage
数组中的所有元素。这将立即将您的平均值设置为当前值:
process (clk, reset)
begin
if (reset = '1') then
out_val <= 0;
stage <= (others => data_in(11 downto 0));
sum <= resize(255 * signed(data_in(11 downto 0)), sum'length);
elsif rising_edge(clk) then
...
最后,如果要使用上述代码为两个不同的信号保持两个单独的平均值,只需实例化平均值实体两次:
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: out signed(11 downto 0);
channel_2_average: out signed(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);
channel_2_average <= to_signed(average_2, 12);
end;
我现在将在fpga上检查结果,并让您知道。这会加快进程吗?我的意思是,我会很快得到值吗?因为我会在使用上述代码2分钟后得到稳定值,如100mA。使用上述代码,我会得到以下错误:错误(10327):adc处的VHDL错误。vhd(103):无法确定运算符“*”的定义--找到了0个可能的定义。您尝试包括使用ieee.numeric\u std.all代码>?是的,我收到了上面的错误。我包括以下库:库ieee;使用ieee.std_logic_1164.all;使用ieee.std_logic_unsigned.all;使用ieee.numeric_std.all;现在我得到另一个错误:error(10344):adc处的VHDL表达式错误。vhd(103):表达式有24个元素,但必须有20个元素
library ieee;
use ieee.std_logic_1164.all;
entity moving_average is
generic(
SAMPLES_COUNT: integer := 256
);
port (
sample: in integer;
average: out integer;
clock: in std_logic;
reset: in std_logic
);
end;
architecture rtl of moving_average is
signal samples_fifo: integer_vector(1 to SAMPLES_COUNT);
signal sum: integer;
begin
process (clock, reset) begin
if reset then
samples_fifo <= (others => sample);
sum <= SAMPLES_COUNT * sample;
elsif rising_edge(clock) then
samples_fifo <= sample & samples_fifo(1 to SAMPLES_COUNT-1);
sum <= sum + sample - samples_fifo(SAMPLES_COUNT);
end if;
end process;
average <= sum / SAMPLES_COUNT;
end;
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: out signed(11 downto 0);
channel_2_average: out signed(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);
channel_2_average <= to_signed(average_2, 12);
end;
library ieee;
use ieee.std_logic_1164.all;
entity moving_average is
generic(
SAMPLES_COUNT: integer := 256
);
port (
sample: in integer;
average: out integer;
clock: in std_logic;
reset: in std_logic;
load: in std_logic
);
end;
architecture rtl of moving_average is
signal samples_fifo: integer_vector(1 to SAMPLES_COUNT);
signal sum: integer;
begin
process (clock, reset) begin
if reset then
samples_fifo <= (others => sample);
sum <= SAMPLES_COUNT * sample;
elsif rising_edge(clock) then
if load then
samples_fifo <= (others => sample);
sum <= SAMPLES_COUNT * sample;
else
samples_fifo <= sample & samples_fifo(1 to SAMPLES_COUNT-1);
sum <= sum + sample - samples_fifo(SAMPLES_COUNT);
end if;
end if;
end process;
average <= sum / SAMPLES_COUNT;
end;