我正在尝试将8个ADC的样本值相加。将它们除以8并通过DAC返回结果。我做了一个案例陈述,让用户可以在总结整个或只输出一个频道之间做出选择。 我遇到的问题是结果是“闪烁”。它经常做它必须做的事情,但有时它给出了看起来更高的值。 个别频道似乎也比总和值差得多。我觉得它综合了两种不同的东西,用于求和和个别频道或其他东西。 我认为它可能与我如何总结向量有关,但我没有足够的经验来判断我所做的事情是否错误。 有没有人知道我做错了什么。
代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY sum IS
PORT(
CLK_IN : IN STD_LOGIC; -- 200MHz
RESET : IN STD_LOGIC;
SUM_EN : IN STD_LOGIC;
SUM_VALID : IN STD_LOGIC;
CHANNEL_IN_1 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_2 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_3 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_4 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_5 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_6 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_7 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_8 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
MODE_DATA : IN std_logic_vector(3 DOWNTO 0);
DATA_OUT : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := x"80";
SUM_READY : OUT STD_LOGIC := '0');
END sum;
ARCHITECTURE behaviour OF sum IS
-- input output registers
SIGNAL r_sum_en : STD_LOGIC := '0';
SIGNAL r_sum_en_edge : STD_LOGIC := '0';
SIGNAL r_sum_valid : STD_LOGIC := '0';
SIGNAL r_sum_ready : STD_LOGIC := '0';
SIGNAL r_channel_in_1 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_2 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_3 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_4 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_5 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_6 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_7 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_mode_data : STD_LOGIC_VECTOR( 3 DOWNTO 0 ) := (others => '0');
SIGNAL r_data_out : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := x"80";
-- logic signals
TYPE machine IS (idle, initialise, summing, waiting, averaging, delivering);
SIGNAL state : machine;
BEGIN
r_channel_in_1 <= CHANNEL_IN_1 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_2 <= CHANNEL_IN_2 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_3 <= CHANNEL_IN_3 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_4 <= CHANNEL_IN_4 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_5 <= CHANNEL_IN_5 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_6 <= CHANNEL_IN_6 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_7 <= CHANNEL_IN_7 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_8 <= CHANNEL_IN_8 WHEN r_sum_en = '1' ELSE x"80";
r_sum_en <= SUM_EN;
r_mode_data <= MODE_DATA;
r_sum_valid <= SUM_VALID;
DATA_OUT <= r_data_out;
SUM_READY <= r_sum_ready;
PROCESS (CLK_IN, RESET) IS
VARIABLE average : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_1 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_2 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_3 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_4 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_5 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_6 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_7 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_8 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
BEGIN
IF RESET = '1' THEN
r_sum_ready <= '0';
r_data_out <= x"80";
hold_channel_1 := (others => '0');
hold_channel_2 := (others => '0');
hold_channel_3 := (others => '0');
hold_channel_4 := (others => '0');
hold_channel_5 := (others => '0');
hold_channel_6 := (others => '0');
hold_channel_7 := (others => '0');
hold_channel_8 := (others => '0');
ELSIF rising_edge(CLK_IN) THEN
CASE state IS
WHEN idle =>
r_sum_en_edge <= r_sum_en;
IF r_sum_en = '1' AND r_sum_en_edge = '0' THEN
state <= initialise;
ELSE state <= idle; END IF;
r_sum_ready <= '0';
r_sum_ready <= '0';
r_data_out <= x"80";
hold_channel_1 := x"080";
hold_channel_2 := x"080";
hold_channel_3 := x"080";
hold_channel_4 := x"080";
hold_channel_5 := x"080";
hold_channel_6 := x"080";
hold_channel_7 := x"080";
hold_channel_8 := x"080";
WHEN initialise =>
IF r_sum_valid = '1' THEN
state <= summing;
hold_channel_1(7 DOWNTO 0) := r_channel_in_1;
hold_channel_2(7 DOWNTO 0) := r_channel_in_2;
hold_channel_3(7 DOWNTO 0) := r_channel_in_3;
hold_channel_4(7 DOWNTO 0) := r_channel_in_4;
hold_channel_5(7 DOWNTO 0) := r_channel_in_5;
hold_channel_6(7 DOWNTO 0) := r_channel_in_6;
hold_channel_7(7 DOWNTO 0) := r_channel_in_7;
hold_channel_8(7 DOWNTO 0) := r_channel_in_8;
ELSE
state <= initialise;
END IF;
r_sum_ready <= '0';
WHEN summing =>
CASE r_mode_data IS
WHEN x"0" => average := hold_channel_1 + hold_channel_2 + hold_channel_3 + hold_channel_4 + hold_channel_5 + hold_channel_6 + hold_channel_7 + hold_channel_8 ;
WHEN x"1" => average := hold_channel_1;
WHEN x"2" => average := hold_channel_2;
WHEN x"3" => average := hold_channel_3;
WHEN x"4" => average := hold_channel_4;
WHEN x"5" => average := hold_channel_5;
WHEN x"6" => average := hold_channel_6;
WHEN x"7" => average := hold_channel_7;
WHEN x"8" => average := hold_channel_8;
WHEN others => null;
END CASE;
state <= waiting;
r_sum_ready <= '0';
WHEN waiting =>
state <= averaging;
r_sum_ready <= '0';
WHEN averaging =>
CASE r_mode_data IS
WHEN x"0" => r_data_out <= average (10 DOWNTO 3);
WHEN others => r_data_out <= average (7 DOWNTO 0);
END CASE;
r_sum_ready <= '0';
state <= delivering;
WHEN delivering =>
r_sum_ready <= '1';
IF r_sum_en = '1' THEN
state <= initialise;
ELSE state <= idle; END IF;
WHEN others =>
state <= idle;
END CASE;
END IF;
END PROCESS;
END ARCHITECTURE;