Major Rewrite of feedback_loop

Another scaling factor was added and both input signals can now be
independenly scaled. In Single Input Mode only Input 1 is passed to the
output (negated if configured as negative feddback). In double input
mode Input 2 is added/subtracted from Input 1 (in1 +/- in2). The delay
line is only applied to Input 2.
Addsub was removed from the design (all Additions and Subtractions are
directly implemented in VHDL code).
Config signals were latched to follow the data flow path and prevent
glitches on certain events.
Vivado Project updated.
Single Package containing all needed pre-calculated sine arrays.
General Code Cleanup.
This commit is contained in:
Greek 2021-03-28 12:32:56 +02:00
parent 9d6838aca3
commit e6b05276d8
16 changed files with 446 additions and 458 deletions

View File

@ -8,39 +8,35 @@ add wave -noupdate /feedback_loop_tb/adc_data_in1
add wave -noupdate /feedback_loop_tb/adc_data_in2 add wave -noupdate /feedback_loop_tb/adc_data_in2
add wave -noupdate /feedback_loop_tb/adc_cs_n add wave -noupdate /feedback_loop_tb/adc_cs_n
add wave -noupdate -divider CONFIG add wave -noupdate -divider CONFIG
add wave -noupdate /feedback_loop_tb/factor
add wave -noupdate /feedback_loop_tb/addsub_mode add wave -noupdate /feedback_loop_tb/addsub_mode
add wave -noupdate /feedback_loop_tb/add_input_mux add wave -noupdate /feedback_loop_tb/add_input_mux
add wave -noupdate -radix unsigned /feedback_loop_tb/delay add wave -noupdate -radix unsigned /feedback_loop_tb/delay
add wave -noupdate -radix binary /feedback_loop_tb/uut/factor1
add wave -noupdate -radix binary /feedback_loop_tb/uut/factor2
add wave -noupdate -divider INPUT add wave -noupdate -divider INPUT
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/adc_data1 add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/adc_data1
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/adc_data2 add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/adc_data2
add wave -noupdate /feedback_loop_tb/uut/adc_done add wave -noupdate /feedback_loop_tb/uut/adc_done
add wave -noupdate -radix hexadecimal /feedback_loop_tb/input2
add wave -noupdate -divider OUTPUT
add wave -noupdate /feedback_loop_tb/uut/addsub_done
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/addsub_out
add wave -noupdate -divider TESTBENCH add wave -noupdate -divider TESTBENCH
add wave -noupdate /feedback_loop_tb/adc_stage add wave -noupdate /feedback_loop_tb/adc_stage
add wave -noupdate /feedback_loop_tb/cnt1 add wave -noupdate /feedback_loop_tb/cnt1
add wave -noupdate /feedback_loop_tb/cnt2 add wave -noupdate /feedback_loop_tb/cnt2
add wave -noupdate -divider SIGNAL add wave -noupdate -divider SIGNAL
add wave -noupdate -format Analog-Step -height 200 -max 4096.0 -radix unsigned /feedback_loop_tb/input1 add wave -noupdate -expand -group ANALOG -format Analog-Step -height 200 -max 4096.0 -radix unsigned /feedback_loop_tb/input1
add wave -noupdate -format Analog-Step -height 200 -max 4094.9999999999995 -radix unsigned /feedback_loop_tb/input2 add wave -noupdate -expand -group ANALOG -format Analog-Step -height 200 -max 4094.9999999999995 -radix unsigned /feedback_loop_tb/input2
add wave -noupdate -format Analog-Step -height 200 -max 65536.0 -radix unsigned /feedback_loop_tb/output add wave -noupdate -expand -group ANALOG -format Analog-Step -height 200 -max 65536.0 -radix unsigned /feedback_loop_tb/output
add wave -noupdate -divider MISC add wave -noupdate -divider MISC
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/scaler_1_out add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/data1_B
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/scaler_2_out add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/data2_B
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/scaler_offset_1 add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/scaler_offset_1
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/scaler_offset_2 add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/scaler_offset_2
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/inputA_wide add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/data1_C
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/inputB_wide add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/data2_C
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/inputA add wave -noupdate /feedback_loop_tb/uut/done_II
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/inputB add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/data_out
add wave -noupdate -radix hexadecimal /feedback_loop_tb/uut/addsub_out add wave -noupdate /feedback_loop_tb/uut/done_IV
add wave -noupdate /feedback_loop_tb/uut/scaler_done
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {399500000000 fs} 0} WaveRestoreCursors {{Cursor 4} {101850000000 fs} 0}
quietly wave cursor active 1 quietly wave cursor active 1
configure wave -namecolwidth 150 configure wave -namecolwidth 150
configure wave -valuecolwidth 100 configure wave -valuecolwidth 100
@ -56,4 +52,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {371218089984 fs} {506777995264 fs} WaveRestoreZoom {0 fs} {535391147585 fs}

View File

@ -1,76 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Library UNISIM;
use UNISIM.vcomponents.all;
Library UNIMACRO;
use UNIMACRO.vcomponents.all;
-- Add/Sub
-- This entity adds or subtracts inputs 'A' and 'B', depending on 'mode' (1 = add, 0 = sub).
-- If 'cap' is high, on Overfolw/Underflow conditions the result is capped at max/min value.
entity addsub is
generic (
PIPELINE_STAGES : integer := 1;
DATA_WIDTH : integer := 16
);
port (
clk : in std_logic;
reset : in std_logic;
mode : in std_logic;
cap : in std_logic;
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
B : in std_logic_vector(DATA_WIDTH-1 downto 0);
RES : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end entity;
architecture arch of addsub is
--*****SIGNAl DECLARATION
signal result : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
signal carry : std_logic := '0';
begin
ADDSUB_MACRO_inst : ADDSUB_MACRO
generic map (
DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "7SERIES", "SPARTAN6"
LATENCY => PIPELINE_STAGES, -- Desired clock cycle latency, 0-2
WIDTH => DATA_WIDTH -- Input / Output bus width, 1-48
)
port map (
CARRYOUT => open, -- 1-bit carry-out output signal
RESULT => result, -- Add/sub result output, width defined by WIDTH generic
A => A, -- Input A bus, width defined by WIDTH generic
ADD_SUB => mode, -- 1-bit add/sub input, high selects add, low selects subtract
B => B, -- Input B bus, width defined by WIDTH generic
CARRYIN => '0', -- 1-bit carry-in input
CE => '1', -- 1-bit clock enable input
CLK => clk, -- 1-bit clock input
RST => reset -- 1-bit active high synchronous reset
);
clamp : process(all)
begin
--DEFAULT VALUE
RES <= result;
--Overflow/Underflow
if(carry = '1' and cap = '1') then
--ADD
if(mode = '1') then
--CAP AT MAX VALUE
RES <= (others => '1');
--SUB
else
--CAP AT ZERO
RES <= (others => '0');
end if;
end if;
end process;
end architecture;

View File

@ -14,8 +14,9 @@ use work.typedef_package.all;
-- mem_data(63) : Slot Enable -- mem_data(63) : Slot Enable
-- mem_data(62) : Addsub_mode -- mem_data(62) : Addsub_mode
-- mem_data(61) : Add_input_mux -- mem_data(61) : Add_input_mux
-- mem_data(47-40) : delay -- mem_data(57-42) : delay
-- mem_data(36-32) : factor -- mem_data(41-37) : factor1
-- mem_data(36-32) : factor2
-- mem_data(31-0) : timestamp -- mem_data(31-0) : timestamp
@ -33,7 +34,8 @@ entity feedback_controller is
addsub_mode : out std_logic; addsub_mode : out std_logic;
add_input_mux : out std_logic; add_input_mux : out std_logic;
delay : out std_logic_vector(DELAY_WIDTH-1 downto 0); delay : out std_logic_vector(DELAY_WIDTH-1 downto 0);
factor : out std_logic_vector(FACTOR_WIDTH-1 downto 0) factor1 : out std_logic_vector(FACTOR_WIDTH-1 downto 0);
factor2 : out std_logic_vector(FACTOR_WIDTH-1 downto 0)
); );
end entity; end entity;
@ -47,7 +49,7 @@ architecture arch of feedback_controller is
signal sync_pulse_arrived : std_logic; signal sync_pulse_arrived : std_logic;
signal addsub_mode_next, addsub_mode_sig, add_input_mux_next, add_input_mux_sig : std_logic := '0'; signal addsub_mode_next, addsub_mode_sig, add_input_mux_next, add_input_mux_sig : std_logic := '0';
signal delay_next, delay_sig : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0'); signal delay_next, delay_sig : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0');
signal factor_next, factor_sig : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0'); signal factor1_next, factor1_sig, factor2_next, factor2_sig : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0');
begin begin
@ -58,7 +60,8 @@ begin
addsub_mode <= addsub_mode_sig; addsub_mode <= addsub_mode_sig;
add_input_mux <= add_input_mux_sig; add_input_mux <= add_input_mux_sig;
delay <= delay_sig; delay <= delay_sig;
factor <= factor_sig; factor1 <= factor1_sig;
factor2 <= factor2_sig;
ctrl : process(all) ctrl : process(all)
begin begin
@ -67,7 +70,8 @@ begin
addsub_mode_next <= addsub_mode_sig; addsub_mode_next <= addsub_mode_sig;
add_input_mux_next <= add_input_mux_sig; add_input_mux_next <= add_input_mux_sig;
delay_next <= delay_sig; delay_next <= delay_sig;
factor_next <= factor_sig; factor1_next <= factor1_sig;
factor2_next <= factor2_sig;
if(mem_data(CONFIG_DATA_WIDTH-1) = '1') then if(mem_data(CONFIG_DATA_WIDTH-1) = '1') then
-- If timestamp is reached (or exceeded), apply configuration and fetch next configuration -- If timestamp is reached (or exceeded), apply configuration and fetch next configuration
@ -75,8 +79,9 @@ begin
if (unsigned(timer) >= unsigned(mem_data(TIMESTAMP_WIDTH-1 downto 0))) then if (unsigned(timer) >= unsigned(mem_data(TIMESTAMP_WIDTH-1 downto 0))) then
addsub_mode_next <= mem_data(CONFIG_DATA_WIDTH-2); addsub_mode_next <= mem_data(CONFIG_DATA_WIDTH-2);
add_input_mux_next <= mem_data(CONFIG_DATA_WIDTH-3); add_input_mux_next <= mem_data(CONFIG_DATA_WIDTH-3);
delay_next <= mem_data(CONFIG_DATA_WIDTH-17 downto CONFIG_DATA_WIDTH-16-DELAY_WIDTH); factor2_next <= mem_data(TIMESTAMP_WIDTH+FACTOR_WIDTH-1 downto TIMESTAMP_WIDTH);
factor_next <= mem_data(TIMESTAMP_WIDTH+FACTOR_WIDTH-1 downto TIMESTAMP_WIDTH); factor1_next <= mem_data(TIMESTAMP_WIDTH+FACTOR_WIDTH+FACTOR_WIDTH-1 downto TIMESTAMP_WIDTH+FACTOR_WIDTH);
delay_next <= mem_data(TIMESTAMP_WIDTH+FACTOR_WIDTH+FACTOR_WIDTH+DELAY_WIDTH-1 downto TIMESTAMP_WIDTH+FACTOR_WIDTH+FACTOR_WIDTH);
slot_nr_next <= std_logic_vector(unsigned(slot_nr) + inc); slot_nr_next <= std_logic_vector(unsigned(slot_nr) + inc);
end if; end if;
@ -91,13 +96,15 @@ begin
addsub_mode_sig <= '0'; addsub_mode_sig <= '0';
add_input_mux_sig <= '0'; add_input_mux_sig <= '0';
delay_sig <= (others => '0'); delay_sig <= (others => '0');
factor_sig <= (others => '0'); factor1_sig <= (others => '0');
factor2_sig <= (others => '0');
else else
slot_nr <= slot_nr_next; slot_nr <= slot_nr_next;
addsub_mode_sig <= addsub_mode_next; addsub_mode_sig <= addsub_mode_next;
add_input_mux_sig <= add_input_mux_next; add_input_mux_sig <= add_input_mux_next;
delay_sig <= delay_next; delay_sig <= delay_next;
factor_sig <= factor_next; factor1_sig <= factor1_next;
factor2_sig <= factor2_next;
end if; end if;
end if; end if;
end process; end process;

View File

@ -34,9 +34,10 @@ entity feedback_loop is
dac_sclk : out std_logic; -- PMOD-DA3 dac_sclk : out std_logic; -- PMOD-DA3
-- DYNAMIC CONFIGURATION -- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB) addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
add_input_mux : in std_logic; -- (1=ADC Input 2, 0=GND) add_input_mux : in std_logic; -- (1=Double Input 2, 0=Single Input)
delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- unsigned delay clock count delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- Unsigned delay clock count
factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- 1Q3 Fixed Point factor1 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
factor2 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
-- DEBUG -- DEBUG
reset_debug : in std_logic; reset_debug : in std_logic;
adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0); adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
@ -48,10 +49,6 @@ end entity;
architecture arch of feedback_loop is architecture arch of feedback_loop is
--*****SIGNAL DECLARATION*****
signal adc_data1, adc_data2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal adc_done : std_logic := '0';
--*****COMPONENT DECLARATION***** --*****COMPONENT DECLARATION*****
component pmod_ad1_ctrl is component pmod_ad1_ctrl is
generic( generic(
@ -105,22 +102,6 @@ architecture arch of feedback_loop is
); );
end component; end component;
component addsub is
generic (
PIPELINE_STAGES : integer := 1;
DATA_WIDTH : integer := 16
);
port (
clk : in std_logic;
reset : in std_logic;
mode : in std_logic;
cap : in std_logic;
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
B : in std_logic_vector(DATA_WIDTH-1 downto 0);
RES : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
component delay_line is component delay_line is
generic ( generic (
DATA_WIDTH : integer := 12; DATA_WIDTH : integer := 12;
@ -142,13 +123,16 @@ architecture arch of feedback_loop is
constant FACTOR_ONE : unsigned(FACTOR_WIDTH-1 downto 0) := (FACTOR_WIDTH-1 => '1', others => '0'); constant FACTOR_ONE : unsigned(FACTOR_WIDTH-1 downto 0) := (FACTOR_WIDTH-1 => '1', others => '0');
--*****SIGNAL DECLARATION***** --*****SIGNAL DECLARATION*****
signal delay_out : std_logic_vector(ADC_DATA_WIDTH downto 0) := (others => '0'); signal adc_data1, adc_data2, adc_data1_latch : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal tmp2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0'); signal adc_done : std_logic := '0';
signal inputA_wide, inputB_wide : std_logic_vector(DAC_DATA_WIDTH downto 0) := (others => '0'); signal data1_A : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal addsub_out, inputA, inputB : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0'); signal data2_A : std_logic_vector(ADC_DATA_WIDTH downto 0) := (others => '0');
signal scaler_1_out, scaler_2_out, scaler_offset_1, scaler_offset_2 : std_logic_vector(DAC_DATA_WIDTH downto 0) := (others => '0'); signal data2_C, data1_C : std_logic_vector(DAC_DATA_WIDTH downto 0) := (others => '0');
signal scaler_done, addsub_done : std_logic := '0'; signal data_out, data2_D, data1_D : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0');
signal offset_factor, tmp : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0'); signal data1_B, data2_B, scaler_offset_1, scaler_offset_2 : std_logic_vector(DAC_DATA_WIDTH downto 0) := (others => '0');
signal done_II, done_IV : std_logic := '0';
signal offset_factor1, offset_factor2, factor1_latch, factor2_latch : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0');
signal add_input_mux_latch, addsub_mode_latch : std_logic := '0';
begin begin
@ -173,7 +157,29 @@ begin
); );
--*****STAGE II***** --*****STAGE II*****
delay_line_inst : delay_line
-- NOTE: The Input1 Signal has to be latched if the delay line is used, so that
-- there is a valid Signal to do operations with after the delay line.
latch_1_prc : process (clk)
begin
if rising_edge(clk) then
if (adc_done = '1') then
adc_data1_latch <= adc_data1;
end if;
end if;
end process;
data1_prc : process (all)
begin
-- If delay_line disabled or Signle Input Mode
if (delay = (delay'range => '0') or add_input_mux = '0') then
data1_A <= adc_data1;
else
data1_A <= adc_data1_latch;
end if;
end process;
delay_line_2_inst : delay_line
generic map( generic map(
DATA_WIDTH => ADC_DATA_WIDTH+1, DATA_WIDTH => ADC_DATA_WIDTH+1,
DELAY_WIDTH => DELAY_WIDTH, DELAY_WIDTH => DELAY_WIDTH,
@ -183,39 +189,46 @@ begin
clk => clk, clk => clk,
reset => reset, reset => reset,
delay => delay, delay => delay,
data_in => (adc_done & adc_data1), data_in => (adc_done & adc_data2),
data_out => delay_out data_out => data2_A
); );
latch_prc : process (all) offset_factor_1_prc : process (all)
variable tmp_res : unsigned(FACTOR_WIDTH-1 downto 0) := (others => '0');
begin begin
if (delay = (delay'range => '0')) then if (factor1(FACTOR_WIDTH-1) = '1') then
tmp2 <= adc_data2; offset_factor1 <= "0" & std_logic_vector(factor1(FACTOR_WIDTH-2 downto 0));
elsif rising_edge(clk) then else
if (adc_done = '1') then tmp_res := FACTOR_ONE - unsigned(factor1);
tmp2 <= adc_data2; offset_factor1 <= "0" & std_logic_vector(tmp_res(FACTOR_WIDTH-2 downto 0));
end if;
end if; end if;
end process; end process;
addsub_offset_inst : addsub offset_factor_2_prc : process (all)
generic map( variable tmp_res : unsigned(FACTOR_WIDTH-1 downto 0) := (others => '0');
PIPELINE_STAGES => 0, begin
DATA_WIDTH => FACTOR_WIDTH if (factor2(FACTOR_WIDTH-1) = '1') then
) offset_factor2 <= "0" & std_logic_vector(factor2(FACTOR_WIDTH-2 downto 0));
port map( else
clk => clk, tmp_res := FACTOR_ONE - unsigned(factor2);
reset => reset, offset_factor2 <= "0" & std_logic_vector(tmp_res(FACTOR_WIDTH-2 downto 0));
mode => '0', end if;
cap => '0', end process;
A => (FACTOR_WIDTH-1 => '1', others => '0'),
B => factor,
RES => tmp
);
offset_factor <= tmp when (factor(FACTOR_WIDTH-1) = '0') else ("0" & factor(FACTOR_WIDTH-2 downto 0)); -- NOTE: We delay the config signals to synchronize them with the data flow and
-- prevent glitches in the case that the config is changed between the stages.
config_latch : process (clk)
begin
if rising_edge(clk) then
factor1_latch <= factor1;
factor2_latch <= factor2;
add_input_mux_latch <= add_input_mux;
addsub_mode_latch <= addsub_mode;
end if;
end process;
--*****STAGE III***** --*****STAGE III*****
scaler_1_inst : scaler scaler_1_inst : scaler
generic map( generic map(
DATA_WIDTH => ADC_DATA_WIDTH, DATA_WIDTH => ADC_DATA_WIDTH,
@ -224,22 +237,9 @@ begin
) )
port map( port map(
clk => clk, clk => clk,
data_in => delay_out(ADC_DATA_WIDTH-1 downto 0), data_in => data1_A,
factor => factor, factor => factor1,
data_out => scaler_1_out data_out => data1_B
);
scaler_2_inst : scaler
generic map(
DATA_WIDTH => ADC_DATA_WIDTH,
FACTOR_WIDTH => FACTOR_WIDTH,
PIPELINE_STAGES => 1
)
port map(
clk => clk,
data_in => tmp2,
factor => "10101", --1.32
data_out => scaler_2_out
); );
scaler_offset_1_inst : scaler scaler_offset_1_inst : scaler
@ -251,10 +251,45 @@ begin
port map( port map(
clk => clk, clk => clk,
data_in => (ADC_DATA_WIDTH-1 => '0', others => '1'), data_in => (ADC_DATA_WIDTH-1 => '0', others => '1'),
factor => offset_factor, factor => offset_factor1,
data_out => scaler_offset_1 data_out => scaler_offset_1
); );
addsub_1_prc : process (all)
begin
if (factor1_latch(FACTOR_WIDTH-1) = '1') then
data1_C <= std_logic_vector(unsigned(data1_B) - unsigned(scaler_offset_1));
else
data1_C <= std_logic_vector(unsigned(data1_B) + unsigned(scaler_offset_1));
end if;
end process;
cap_1_prc : process(all)
begin
if (data1_C(DAC_DATA_WIDTH) = '1') then
if (factor1_latch(FACTOR_WIDTH-1) = '1' and data1_B(DAC_DATA_WIDTH) = '0') then
data1_D <= (others => '0');
else
data1_D <= (others => '1');
end if;
else
data1_D <= data1_C(DAC_DATA_WIDTH-1 downto 0);
end if;
end process;
scaler_2_inst : scaler
generic map(
DATA_WIDTH => ADC_DATA_WIDTH,
FACTOR_WIDTH => FACTOR_WIDTH,
PIPELINE_STAGES => 1
)
port map(
clk => clk,
data_in => data2_A(ADC_DATA_WIDTH-1 downto 0),
factor => factor2,
data_out => data2_B
);
scaler_offset_2_inst : scaler scaler_offset_2_inst : scaler
generic map( generic map(
DATA_WIDTH => ADC_DATA_WIDTH, DATA_WIDTH => ADC_DATA_WIDTH,
@ -264,206 +299,115 @@ begin
port map( port map(
clk => clk, clk => clk,
data_in => (ADC_DATA_WIDTH-1 => '0', others => '1'), data_in => (ADC_DATA_WIDTH-1 => '0', others => '1'),
factor => "00101", --0.32 factor => offset_factor2,
data_out => scaler_offset_2 data_out => scaler_offset_2
); );
process(clk) addsub_2_prc : process (all)
begin
if (factor2_latch(FACTOR_WIDTH-1) = '1') then
data2_C <= std_logic_vector(unsigned(data2_B) - unsigned(scaler_offset_2));
else
data2_C <= std_logic_vector(unsigned(data2_B) + unsigned(scaler_offset_2));
end if;
end process;
cap_2_prc : process(all)
begin
if (data2_C(DAC_DATA_WIDTH) = '1') then
if (factor2_latch(FACTOR_WIDTH-1) = '1' and data2_B(DAC_DATA_WIDTH) = '0') then
data2_D <= (others => '0');
else
data2_D <= (others => '1');
end if;
else
data2_D <= data2_C(DAC_DATA_WIDTH-1 downto 0);
end if;
end process;
done_II_prc : process(clk)
begin begin
if (rising_edge(clk)) then if (rising_edge(clk)) then
if (reset = '1') then if (reset = '1') then
scaler_done <= '0'; done_II <= '0';
else else
scaler_done <= delay_out(ADC_DATA_WIDTH); -- Signle Input Mode
if (add_input_mux_latch = '0') then
-- Synchronize on ADC Output
done_II <= adc_done;
else
-- Synchronize on Delay Line Output
done_II <= data2_A(ADC_DATA_WIDTH);
end if;
end if; end if;
end if; end if;
end process; end process;
addsub_1_inst : addsub
generic map(
PIPELINE_STAGES => 0,
DATA_WIDTH => DAC_DATA_WIDTH+1
)
port map(
clk => clk,
reset => reset,
mode => not factor(FACTOR_WIDTH-1),
cap => '0',
A => scaler_1_out,
B => scaler_offset_1,
RES => inputB_wide
);
addsub_2_inst : addsub
generic map(
PIPELINE_STAGES => 0,
DATA_WIDTH => DAC_DATA_WIDTH+1
)
port map(
clk => clk,
reset => reset,
mode => '0',
cap => '0',
A => scaler_2_out,
B => scaler_offset_2,
RES => inputA_wide
);
cap_B_prc : process(all)
begin
if (inputB_wide(DAC_DATA_WIDTH) = '1') then
if (factor(FACTOR_WIDTH-1) = '1' and scaler_1_out(DAC_DATA_WIDTH) = '0') then
inputB <= (others => '0');
else
inputB <= (others => '1');
end if;
else
inputB <= inputB_wide(DAC_DATA_WIDTH-1 downto 0);
end if;
end process;
cap_A_prc : process(all)
begin
if (inputA_wide(DAC_DATA_WIDTH) = '1') then
--if (factor(FACTOR_WIDTH-1) = '1' and scaler_2_out(DAC_DATA_WIDTH) = '0') then
if (scaler_2_out(DAC_DATA_WIDTH) = '0') then
inputA <= (others => '0');
else
inputA <= (others => '1');
end if;
else
inputA <= inputA_wide(DAC_DATA_WIDTH-1 downto 0);
end if;
end process;
--*****STAGE IV***** --*****STAGE IV*****
--mux: process(all) add_sub_prc : process (clk)
--begin
-- if (add_input_mux = '1') then
-- if (inputA_wide(DAC_DATA_WIDTH) = '1') then
-- --TODO: CAP Needed?
-- inputA <= (others => '0');
-- else
-- inputA <= inputA_wide(DAC_DATA_WIDTH-1 downto 0);
-- end if;
-- else
-- if (addsub_mode = '1') then
-- inputA <= (others => '0');
-- else
-- inputA <= (others => '1');
-- end if;
-- end if;
--end process;
--add_sub_prc : process (all)
-- variable tmp_res : unsigned(inputB'length-1 downto 0) := (others => '0');
--begin
-- if rising_edge(clk) then
-- if (reset = '1') then
-- addsub_out <= (others => '0');
-- else
-- -- Both Inputs
-- if (add_input_mux = '1') then
-- -- ADD
-- if (addsub_mode = '1') then
-- tmp_res := unsigned(inputB) + unsigned(inputA);
-- -- SUB
-- else
-- tmp_res := unsigned(inputB) - unsigned(inputA);
-- end if;
-- addsub_out <= std_logic_vector(tmp_res + CONST_HALF);
-- -- Single Input
-- else
-- -- ADD
-- if (addsub_mode = '1') then
-- addsub_out <= inputB;
-- -- SUB
-- else
-- addsub_out <= not inputB;--std_logic_vector(CONST_MAX - unsigned(inputB));
-- end if;
-- end if;
-- end if;
-- end if;
--end process;
add_sub_prc : process (all)
variable tmp_res : unsigned(DAC_DATA_WIDTH+1 downto 0) := (others => '0'); variable tmp_res : unsigned(DAC_DATA_WIDTH+1 downto 0) := (others => '0');
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if (reset = '1') then if (reset = '1') then
addsub_out <= (others => '0'); data_out <= (others => '0');
else else
-- Both Inputs -- Double Input Mode
if (add_input_mux = '1') then if (add_input_mux_latch = '1') then
-- ADD -- ADD
if (addsub_mode = '1') then if (addsub_mode_latch = '1') then
tmp_res := unsigned("00" & inputB) + unsigned("00" & inputA); tmp_res := unsigned("00" & data1_D) + unsigned("00" & data2_D);
tmp_res := tmp_res + ("00" & CONST_HALF); tmp_res := tmp_res + ("00" & CONST_HALF);
-- Overflow -- Overflow
if (tmp_res(DAC_DATA_WIDTH+1) = '1') then if (tmp_res(DAC_DATA_WIDTH+1) = '1') then
addsub_out <= (others => '1'); data_out <= (others => '1');
-- Underflow -- Underflow
elsif (tmp_res(DAC_DATA_WIDTH+1 downto DAC_DATA_WIDTH) = "00") then elsif (tmp_res(DAC_DATA_WIDTH+1 downto DAC_DATA_WIDTH) = "00") then
addsub_out <= (others => '0'); data_out <= (others => '0');
else else
addsub_out <= std_logic_vector(tmp_res(DAC_DATA_WIDTH-1 downto 0)); data_out <= std_logic_vector(tmp_res(DAC_DATA_WIDTH-1 downto 0));
end if; end if;
-- SUB -- SUB
else else
tmp_res := unsigned("00" & inputB) - unsigned("00" & inputA); tmp_res := unsigned("00" & data1_D) - unsigned("00" & data2_D);
tmp_res := tmp_res + ("00" & CONST_HALF); tmp_res := tmp_res + ("00" & CONST_HALF);
-- Underflow -- Underflow
if (tmp_res(DAC_DATA_WIDTH+1 downto DAC_DATA_WIDTH) = "11") then if (tmp_res(DAC_DATA_WIDTH+1 downto DAC_DATA_WIDTH) = "11") then
addsub_out <= (others => '0'); data_out <= (others => '0');
-- Overflow -- Overflow
elsif (tmp_res(DAC_DATA_WIDTH) = '1') then elsif (tmp_res(DAC_DATA_WIDTH) = '1') then
addsub_out <= (others => '1'); data_out <= (others => '1');
else else
addsub_out <= std_logic_vector(tmp_res(DAC_DATA_WIDTH-1 downto 0)); data_out <= std_logic_vector(tmp_res(DAC_DATA_WIDTH-1 downto 0));
end if; end if;
end if; end if;
-- Single Input -- Single Input Mode
else else
-- ADD -- ADD
if (addsub_mode = '1') then if (addsub_mode_latch = '1') then
addsub_out <= inputB; data_out <= data1_D;
-- SUB -- SUB
else else
addsub_out <= not inputB;--std_logic_vector(CONST_MAX - unsigned(inputB)); data_out <= not data1_D;
end if; end if;
end if; end if;
end if; end if;
end if; end if;
end process; end process;
-- addsub_instA : addsub done_IV_prc : process(clk)
-- generic map(
-- PIPELINE_STAGES => 1,
-- DATA_WIDTH => DAC_DATA_WIDTH
-- )
-- port map(
-- clk => clk,
-- reset => reset,
-- mode => addsub_mode,
-- cap => add_input_mux,
-- A => inputA,
-- B => inputB,
-- RES => addsub_out
-- );
process(clk)
begin begin
if (rising_edge(clk)) then if (rising_edge(clk)) then
if (reset = '1') then if (reset = '1') then
addsub_done <= '0'; done_IV <= '0';
else else
addsub_done <= scaler_done; done_IV <= done_II;
end if; end if;
end if; end if;
end process; end process;
--*****STAGE V***** --*****STAGE V*****
dac_inst : pmod_da3_ctrl dac_inst : pmod_da3_ctrl
generic map( generic map(
TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT, TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT,
@ -472,8 +416,8 @@ begin
port map( port map(
clk => clk, clk => clk,
reset => reset, reset => reset,
start => addsub_done, start => done_IV,
data => addsub_out, data => data_out,
cs_n => dac_cs_n, cs_n => dac_cs_n,
sdata => dac_data_out, sdata => dac_data_out,
ldac => dac_ldac, ldac => dac_ldac,
@ -497,15 +441,15 @@ begin
elsif (to_integer(unsigned(adc_data2)) >= to_integer(unsigned(adc_data2_max))) then elsif (to_integer(unsigned(adc_data2)) >= to_integer(unsigned(adc_data2_max))) then
adc_data2_max <= adc_data2; adc_data2_max <= adc_data2;
end if; end if;
-- DAC MAX VALUES
elsif (addsub_done = '1') then
if (to_integer(unsigned(addsub_out)) >= to_integer(unsigned(dac_max))) then
dac_max <= addsub_out;
end if;
-- SCALER MAX VALUES -- SCALER MAX VALUES
elsif (scaler_done = '1') then elsif (done_II = '1') then
if (to_integer(unsigned(scaler_1_out)) >= to_integer(unsigned(scaler_max))) then if (to_integer(unsigned(data1_B)) >= to_integer(unsigned(scaler_max))) then
scaler_max <= scaler_1_out(DAC_DATA_WIDTH-1 downto 0); scaler_max <= data1_B(DAC_DATA_WIDTH-1 downto 0);
end if;
-- DAC MAX VALUES
elsif (done_IV = '1') then
if (to_integer(unsigned(data_out)) >= to_integer(unsigned(dac_max))) then
dac_max <= data_out;
end if; end if;
end if; end if;
end if; end if;

View File

@ -76,9 +76,10 @@ architecture arch of feedback_top is
dac_sclk : out std_logic; -- PMOD-DA3 dac_sclk : out std_logic; -- PMOD-DA3
-- DYNAMIC CONFIGURATION -- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB) addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
add_input_mux : in std_logic; -- (1=ADC Input 2, 0=GND) add_input_mux : in std_logic; -- (1=Double Input 2, 0=Single Input)
delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- unsigned delay clock count delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- Unsigned delay clock count
factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- 1Q3 Fixed Point factor1 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
factor2 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
-- DEBUG -- DEBUG
reset_debug : in std_logic; reset_debug : in std_logic;
adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0); adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
@ -102,7 +103,8 @@ architecture arch of feedback_top is
addsub_mode : out std_logic; addsub_mode : out std_logic;
add_input_mux : out std_logic; add_input_mux : out std_logic;
delay : out std_logic_vector(DELAY_WIDTH-1 downto 0); delay : out std_logic_vector(DELAY_WIDTH-1 downto 0);
factor : out std_logic_vector(FACTOR_WIDTH-1 downto 0) factor1 : out std_logic_vector(FACTOR_WIDTH-1 downto 0);
factor2 : out std_logic_vector(FACTOR_WIDTH-1 downto 0)
); );
end component; end component;
@ -142,7 +144,7 @@ architecture arch of feedback_top is
signal clk_20, reset, sync_pulse, standby, reset_debug : std_logic := '0'; signal clk_20, reset, sync_pulse, standby, reset_debug : std_logic := '0';
signal addsub_mode, add_input_mux : std_logic := '0'; signal addsub_mode, add_input_mux : std_logic := '0';
signal delay : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0'); signal delay : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0');
signal factor : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0'); signal factor1, factor2 : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0');
signal adc_data1_max, adc_data2_max : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0'); signal adc_data1_max, adc_data2_max : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal scaler_max, dac_max : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0'); signal scaler_max, dac_max : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0');
signal config_addr : std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0) := (others => '0'); signal config_addr : std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0) := (others => '0');
@ -219,7 +221,8 @@ begin
addsub_mode => addsub_mode, addsub_mode => addsub_mode,
add_input_mux => add_input_mux, add_input_mux => add_input_mux,
delay => delay, delay => delay,
factor => factor, factor1 => factor1,
factor2 => factor2,
reset_debug => reset_debug, reset_debug => reset_debug,
adc_data1_max => adc_data1_max, adc_data1_max => adc_data1_max,
adc_data2_max => adc_data2_max, adc_data2_max => adc_data2_max,
@ -238,7 +241,8 @@ begin
addsub_mode => addsub_mode, addsub_mode => addsub_mode,
add_input_mux => add_input_mux, add_input_mux => add_input_mux,
delay => delay, delay => delay,
factor => factor factor1 => factor1,
factor2 => factor2
); );
xillybus_link_inst : xillybus_link xillybus_link_inst : xillybus_link

View File

@ -1,8 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package sine_package is
type SINE_ARRAY_TYPE is array (0 to 10) of std_logic_vector(11 downto 0);
constant sine : SINE_ARRAY_TYPE := (x"800", x"A2A", x"BA3", x"BF6", x"B06", x"920", x"6E0", x"4FA", x"40A", x"45D", x"5D6");
end package;

View File

@ -1,8 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package sine_package is
type SINE_ARRAY_TYPE is array (0 to 10) of std_logic_vector(11 downto 0);
constant sine : SINE_ARRAY_TYPE := (x"800", x"C53", x"F46", x"FEA", x"E0B", x"A41", x"5BF", x"1F5", x"016", x"0BA", x"3AD");
end package;

View File

@ -1,8 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package sine_package is
type SINE_ARRAY_TYPE is array (0 to 110) of std_logic_vector(11 downto 0);
constant sine : SINE_ARRAY_TYPE := (x"800", x"83A", x"874", x"8AD", x"8E6", x"91E", x"955", x"98B", x"9C0", x"9F3", x"A25", x"A55", x"A83", x"AAF", x"AD9", x"B01", x"B26", x"B48", x"B68", x"B85", x"B9F", x"BB6", x"BCA", x"BDB", x"BE9", x"BF4", x"BFB", x"BFF", x"C00", x"BFD", x"BF8", x"BEF", x"BE3", x"BD3", x"BC1", x"BAB", x"B92", x"B77", x"B58", x"B37", x"B14", x"AED", x"AC5", x"A9A", x"A6C", x"A3D", x"A0C", x"9DA", x"9A6", x"970", x"93A", x"902", x"8CA", x"890", x"857", x"81D", x"7E3", x"7A9", x"770", x"736", x"6FE", x"6C6", x"690", x"65A", x"626", x"5F4", x"5C3", x"594", x"566", x"53B", x"513", x"4EC", x"4C9", x"4A8", x"489", x"46E", x"455", x"43F", x"42D", x"41D", x"411", x"408", x"403", x"400", x"401", x"405", x"40C", x"417", x"425", x"436", x"44A", x"461", x"47B", x"498", x"4B8", x"4DA", x"4FF", x"527", x"551", x"57D", x"5AB", x"5DB", x"60D", x"640", x"675", x"6AB", x"6E2", x"71A", x"753", x"78C", x"7C6");
end package;

View File

@ -1,11 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package sine_package is
type SINE_ARRAY_TYPE is array (0 to 110) of std_logic_vector(11 downto 0);
-- OFFSET: 2048, AMPLITUDE: 2047, FREQUENCY: 10kHz
constant sine2 : SINE_ARRAY_TYPE := (x"800", x"874", x"8E7", x"95A", x"9CC", x"A3C", x"AAA", x"B16", x"B80", x"BE6", x"C4A", x"CAA", x"D06", x"D5E", x"DB2", x"E01", x"E4B", x"E90", x"ECF", x"F09", x"F3D", x"F6B", x"F94", x"FB5", x"FD1", x"FE6", x"FF5", x"FFD", x"FFF", x"FFA", x"FEE", x"FDC", x"FC4", x"FA5", x"F80", x"F55", x"F24", x"EED", x"EB0", x"E6E", x"E26", x"DDA", x"D88", x"D33", x"CD8", x"C7A", x"C18", x"BB3", x"B4B", x"AE0", x"A73", x"A04", x"993", x"921", x"8AE", x"83A", x"7C6", x"752", x"6DF", x"66D", x"5FC", x"58D", x"520", x"4B5", x"44D", x"3E8", x"386", x"328", x"2CD", x"278", x"226", x"1DA", x"192", x"150", x"113", x"0DC", x"0AB", x"080", x"05B", x"03C", x"024", x"012", x"006", x"001", x"003", x"00B", x"01A", x"02F", x"04B", x"06C", x"095", x"0C3", x"0F7", x"131", x"170", x"1B5", x"1FF", x"24E", x"2A2", x"2FA", x"356", x"3B6", x"41A", x"480", x"4EA", x"556", x"5C4", x"634", x"6A6", x"719", x"78C");
-- OFFSET: 2048, AMPLITUDE: 1024, FREQUENCY: 10kHz
constant sine1 : SINE_ARRAY_TYPE := (x"800", x"83A", x"874", x"8AD", x"8E6", x"91E", x"955", x"98B", x"9C0", x"9F3", x"A25", x"A55", x"A83", x"AAF", x"AD9", x"B01", x"B26", x"B48", x"B68", x"B85", x"B9F", x"BB6", x"BCA", x"BDB", x"BE9", x"BF4", x"BFB", x"BFF", x"C00", x"BFD", x"BF8", x"BEF", x"BE3", x"BD3", x"BC1", x"BAB", x"B92", x"B77", x"B58", x"B37", x"B14", x"AED", x"AC5", x"A9A", x"A6C", x"A3D", x"A0C", x"9DA", x"9A6", x"970", x"93A", x"902", x"8CA", x"890", x"857", x"81D", x"7E3", x"7A9", x"770", x"736", x"6FE", x"6C6", x"690", x"65A", x"626", x"5F4", x"5C3", x"594", x"566", x"53B", x"513", x"4EC", x"4C9", x"4A8", x"489", x"46E", x"455", x"43F", x"42D", x"41D", x"411", x"408", x"403", x"400", x"401", x"405", x"40C", x"417", x"425", x"436", x"44A", x"461", x"47B", x"498", x"4B8", x"4DA", x"4FF", x"527", x"551", x"57D", x"5AB", x"5DB", x"60D", x"640", x"675", x"6AB", x"6E2", x"71A", x"753", x"78C", x"7C6");
end package;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -25,9 +25,10 @@ architecture beh of feedback_loop_tb is
dac_sclk : out std_logic; -- PMOD-DA3 dac_sclk : out std_logic; -- PMOD-DA3
-- DYNAMIC CONFIGURATION -- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB) addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
add_input_mux : in std_logic; -- (1=ADC Input 2, 0=GND) add_input_mux : in std_logic; -- (1=Double Input 2, 0=Single Input)
delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- unsigned delay clock count delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- Unsigned delay clock count
factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- 1Q3 Fixed Point factor1 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
factor2 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
-- DEBUG -- DEBUG
reset_debug : in std_logic; reset_debug : in std_logic;
adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0); adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
@ -39,17 +40,33 @@ architecture beh of feedback_loop_tb is
type ADC_STAGE_TYPE is (ZERO, DATA); type ADC_STAGE_TYPE is (ZERO, DATA);
constant ZERO_SIGNAL : SIGNAL_RECORD_TYPE := (
sine => (others => (others => '0')),
len => 1
);
constant HALF_SIGNAL : SIGNAL_RECORD_TYPE := (
sine => (others => x"800"),
len => 1
);
--*****SIGNAL DECLARATION***** --*****SIGNAL DECLARATION*****
signal clk, reset : std_logic := '0'; signal clk, reset : std_logic := '0';
signal adc_data_in1, adc_data_in2, adc_cs_n : std_logic := '0'; signal adc_data_in1, adc_data_in2, adc_cs_n : std_logic := '0';
signal factor : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0'); signal factor1, factor2 : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0');
signal addsub_mode, add_input_mux : std_logic := '0'; signal addsub_mode, add_input_mux : std_logic := '0';
signal delay : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0'); signal delay : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0');
signal adc_stage : ADC_STAGE_TYPE := ZERO; signal adc_stage : ADC_STAGE_TYPE := ZERO;
signal cnt1, cnt2 : integer := 0; signal cnt1, cnt2, cnt3 : integer := 0;
signal input1, input2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0'); signal input1, input2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal output : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0'); signal output : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0');
signal sine_done : std_logic := '0'; signal sig1, sig2 : SIGNAL_RECORD_TYPE := ZERO_SIGNAL;
procedure wait_samples( num : in natural) is
begin
-- Num * Sampling Cadence * Clock Period
wait for num*18*50 ns;
wait until rising_edge(clk);
end procedure;
begin begin
@ -69,7 +86,8 @@ begin
addsub_mode => addsub_mode, addsub_mode => addsub_mode,
add_input_mux => add_input_mux, add_input_mux => add_input_mux,
delay => delay, delay => delay,
factor => factor, factor1 => factor1,
factor2 => factor2,
reset_debug => '0', reset_debug => '0',
adc_data1_max => open, adc_data1_max => open,
adc_data2_max => open, adc_data2_max => open,
@ -92,50 +110,147 @@ begin
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); wait until rising_edge(clk);
reset <= '0'; reset <= '0';
--report "Single Input, Positive Feedback, Scale 1.32, Delay 0"; report "Single Input, Signal 1 [MAX Amplitude, 10kHz], Positive Feedback, Scale 1";
--add_input_mux <= '0'; sig1 <= sine1;
--addsub_mode <= '1'; sig2 <= ZERO_SIGNAL;
--factor <= "10101"; --1.32 add_input_mux <= '0';
--delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH)); addsub_mode <= '1';
--wait until sine_done = '1'; factor1 <= "10000"; --1.0
--report "Single Input, Negative Feedback, Scale 1.32, Delay 0"; factor2 <= "10000"; --1.0
--add_input_mux <= '0'; delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
--addsub_mode <= '0'; wait_samples(sine1.len);
--factor <= "10101"; --1.32 report "Single Input, Signal 1 [MAX Amplitude, 10kHz], Negative Feedback, Scale 1";
--delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH)); sig1 <= sine1;
--wait until sine_done = '1'; sig2 <= ZERO_SIGNAL;
--report "Single Input, Positive Feedback, Scale 0.66, Delay 0"; add_input_mux <= '0';
--add_input_mux <= '0'; addsub_mode <= '0';
--addsub_mode <= '1'; factor1 <= "10000"; --1.0
--factor <= "01010"; --0.66 factor2 <= "10000"; --1.0
--delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH)); delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
--wait until sine_done = '1'; wait_samples(sine1.len);
--report "Single Input, Positive Feedback, Scale 1.32, Delay 500"; report "Single Input, Signal 1 [DAC Adjusted MAX Amplitude, 10kHz], Positive Feedback, Scale 1.32";
--add_input_mux <= '0'; sig1 <= sine3;
--addsub_mode <= '1'; sig2 <= ZERO_SIGNAL;
--factor <= "10101"; --1.32 add_input_mux <= '0';
--delay <= std_logic_vector(to_unsigned(500,DELAY_WIDTH)); addsub_mode <= '1';
--wait until sine_done = '1'; factor1 <= "10101"; --1.32
--report "Double Input, Positive Feedback, Scale 0.66, Delay 0"; factor2 <= "10000"; --1.0
--add_input_mux <= '1'; delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
--addsub_mode <= '1'; wait_samples(sine3.len);
--factor <= "01010"; --0.66 report "Single Input, Signal 1 [MAX Amplitude, 10kHz], Positive Feedback, Scale 1.32";
--delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH)); sig1 <= sine1;
--wait until sine_done = '1'; sig2 <= ZERO_SIGNAL;
report "Double Input, Negative Feedback, Scale 1.32, Delay 0"; add_input_mux <= '0';
addsub_mode <= '1';
factor1 <= "10101"; --1.32
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Single Input, Signal 1 [MAX Amplitude, 10kHz], Positive Feedback, Scale 0.5";
sig1 <= sine1;
sig2 <= ZERO_SIGNAL;
add_input_mux <= '0';
addsub_mode <= '1';
factor1 <= "01000"; --0.5
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Double Input, Signal 1 [HALF Amplitude, 10kHz], Signal 2 [Static HALF], Positive Feedback, Scale1 1, Scale2 1, Delay 0";
sig1 <= sine2;
sig2 <= HALF_SIGNAL;
add_input_mux <= '1';
addsub_mode <= '1';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine2.len);
report "Double Input, Signal 1 [HALF Amplitude, 10kHz], Signal 2 [HALF Amplitude, 10kHz], Positive Feedback, Scale1 1, Scale2 1, Delay 0";
sig1 <= sine2;
sig2 <= sine2;
add_input_mux <= '1';
addsub_mode <= '1';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine2.len);
report "Double Input, Signal 1 [MAX Amplitude, 10kHz], Signal 2 [HALF Amplitude, 10kHz], Positive Feedback, Scale1 1, Scale2 1, Delay 0";
sig1 <= sine1;
sig2 <= sine2;
add_input_mux <= '1';
addsub_mode <= '1';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Double Input, Signal 1 [MAX Amplitude, 10kHz], Signal 2 [MAX Amplitude, 10kHz], Positive Feedback, Scale1 0.75, Scale2 0.25, Delay 0";
sig1 <= sine1;
sig2 <= sine1;
add_input_mux <= '1';
addsub_mode <= '1';
factor1 <= "01100"; --0.75
factor2 <= "00100"; --0.25
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Double Input, Signal 1 [HALF Amplitude, 10kHz], Signal 2 [HALF Amplitude, 10kHz], Negative Feedback, Scale1 1, Scale2 1, Delay 0";
sig1 <= sine2;
sig2 <= sine2;
add_input_mux <= '1'; add_input_mux <= '1';
addsub_mode <= '0'; addsub_mode <= '0';
--factor <= "01010"; --0.66 factor1 <= "10000"; --1.0
factor <= "10101"; --1.32 factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(500,DELAY_WIDTH)); delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait until sine_done = '1'; wait_samples(sine2.len);
report "Double Input, Signal 1 [MAX Amplitude, 10kHz], Signal 2 [HALF Amplitude, 10kHz], Negative Feedback, Scale1 1, Scale2 1, Delay 0";
sig1 <= sine1;
sig2 <= sine2;
add_input_mux <= '1';
addsub_mode <= '0';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Double Input, Signal 1 [Static HALF], Signal 2 [MAX Amplitude, 10kHz], Negative Feedback, Scale1 1, Scale2 1, Delay 0";
sig1 <= HALF_SIGNAL;
sig2 <= sine1;
add_input_mux <= '1';
addsub_mode <= '0';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Double Input, Signal 1 [MAX Amplitude, 10kHz], Signal 2 [HALF Amplitude, 10kHz], Negative Feedback, Scale1 1.32, Scale2 1, Delay 0";
sig1 <= sine1;
sig2 <= sine2;
add_input_mux <= '1';
addsub_mode <= '0';
factor1 <= "10101"; --1.32
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(0,DELAY_WIDTH));
wait_samples(sine1.len);
report "Double Input, Signal 1 [MAX Amplitude, 10kHz], Signal 2 [MAX Amplitude, 10kHz], Positive Feedback, Scale1 1, Scale2 1, Delay 1008";
sig1 <= sine1;
sig2 <= sine1;
add_input_mux <= '1';
addsub_mode <= '1';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(1008,DELAY_WIDTH));
wait_samples(sine1.len+56);
report "Double Input, Signal 1 [HALF Amplitude, 10kHz], Signal 2 [MAX Amplitude, 10kHz], Negative Feedback, Scale1 1, Scale2 1, Delay 504";
sig1 <= sine2;
sig2 <= sine1;
add_input_mux <= '1';
addsub_mode <= '0';
factor1 <= "10000"; --1.0
factor2 <= "10000"; --1.0
delay <= std_logic_vector(to_unsigned(504,DELAY_WIDTH));
wait_samples(sine1.len+28);
wait; wait;
end process; end process;
adc_prc : process (all) adc_prc : process (all)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
sine_done <= '0';
case (adc_stage) is case (adc_stage) is
when ZERO => when ZERO =>
if (adc_cs_n = '0') then if (adc_cs_n = '0') then
@ -147,14 +262,20 @@ begin
end if; end if;
when DATA => when DATA =>
if (adc_cs_n = '0') then if (adc_cs_n = '0') then
cnt1 <= cnt1 - 1; cnt1 <= cnt1 - 1;
if (cnt1 = 0) then if (cnt1 = 0) then
if (cnt2 = sine1'length-1) then -- Signal 1
cnt2 <= 0; if (cnt2 = sig1.len-1) then
sine_done <= '1'; cnt2 <= 0;
else else
cnt2 <= cnt2 + 1; cnt2 <= cnt2 + 1;
end if; end if;
-- Signal 2
if (cnt3 = sig2.len-1) then
cnt3 <= 0;
else
cnt3 <= cnt3 + 1;
end if;
cnt1 <= 0; cnt1 <= 0;
adc_stage <= ZERO; adc_stage <= ZERO;
end if; end if;
@ -167,24 +288,30 @@ begin
adc_data_in1 <= '0'; adc_data_in1 <= '0';
adc_data_in2 <= '0'; adc_data_in2 <= '0';
when DATA => when DATA =>
adc_data_in1 <= sine1(cnt2)(cnt1); adc_data_in1 <= sig1.sine(cnt2)(cnt1);
adc_data_in2 <= sine2(cnt2)(cnt1); adc_data_in2 <= sig2.sine(cnt3)(cnt1);
end case; end case;
end process; end process;
io_prc : process (all) io_prc : process (all)
--alias in1 is <<signal uut.adc_data1 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0)>>; alias in_done is <<signal uut.adc_done : std_logic>>;
--alias in2 is <<signal uut.adc_data2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0)>>; alias in1 is <<signal uut.data1_A : std_logic_vector(ADC_DATA_WIDTH-1 downto 0)>>;
--alias in_done is <<signal uut.adc_done : std_logic>>; alias in2 is <<signal uut.data2_A : std_logic_vector(ADC_DATA_WIDTH downto 0)>>;
alias in1 is <<signal uut.delay_out : std_logic_vector(ADC_DATA_WIDTH downto 0)>>; alias out1 is <<signal uut.data_out : std_logic_vector(DAC_DATA_WIDTH-1 downto 0)>>;
alias in2 is <<signal uut.tmp2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0)>>; alias out_done is <<signal uut.done_IV : std_logic>>;
alias out1 is <<signal uut.addsub_out : std_logic_vector(DAC_DATA_WIDTH-1 downto 0)>>;
alias out_done is <<signal uut.addsub_done : std_logic>>;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if (in1(ADC_DATA_WIDTH) = '1') then -- Signle Input Mode
input1 <= in1(ADC_DATA_WIDTH-1 downto 0); if (add_input_mux = '0') then
input2 <= in2; if (in_done = '1') then
input1 <= in1;
input2 <= in2(ADC_DATA_WIDTH-1 downto 0);
end if;
else
if (in2(ADC_DATA_WIDTH) = '1') then
input1 <= in1;
input2 <= in2(ADC_DATA_WIDTH-1 downto 0);
end if;
end if; end if;
if (out_done = '1') then if (out_done = '1') then
output <= out1; output <= out1;

42
src/sim/sine_package.vhd Normal file
View File

@ -0,0 +1,42 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package sine_package is
type SIGNAL_ARRAY_TYPE is array (0 to 1024) of std_logic_vector(11 downto 0);
type SIGNAL_RECORD_TYPE is record
sine : SIGNAL_ARRAY_TYPE;
len : natural;
end record;
-- ZERO: 2048, AMPLITUDE: 2047, FREQUENCY: 10kHz
constant sine1 : SIGNAL_RECORD_TYPE := (
sine => (x"800", x"873", x"8E5", x"957", x"9C8", x"A37", x"AA4", x"B0F", x"B78", x"BDE", x"C41", x"CA1", x"CFC", x"D54", x"DA7", x"DF6", x"E40", x"E85", x"EC5", x"F00", x"F34", x"F63", x"F8C", x"FAF", x"FCC", x"FE2", x"FF2", x"FFC", x"FFF", x"FFC", x"FF2", x"FE2", x"FCC", x"FAF", x"F8C", x"F63", x"F34", x"F00", x"EC5", x"E85", x"E40", x"DF6", x"DA7", x"D54", x"CFC", x"CA1", x"C41", x"BDE", x"B78", x"B0F", x"AA4", x"A37", x"9C8", x"957", x"8E5", x"873", x"800", x"78D", x"71B", x"6A9", x"638", x"5C9", x"55C", x"4F1", x"488", x"422", x"3BF", x"35F", x"304", x"2AC", x"259", x"20A", x"1C0", x"17B", x"13B", x"100", x"0CC", x"09D", x"074", x"051", x"034", x"01E", x"00E", x"004", x"001", x"004", x"00E", x"01E", x"034", x"051", x"074", x"09D", x"0CC", x"100", x"13B", x"17B", x"1C0", x"20A", x"259", x"2AC", x"304", x"35F", x"3BF", x"422", x"488", x"4F1", x"55C", x"5C9", x"638", x"6A9", x"71B", x"78D", others => x"000"),
len => 112
);
-- ZERO: 2048, AMPLITUDE: 1024, FREQUENCY: 10kHz
constant sine2 : SIGNAL_RECORD_TYPE := (
sine => (x"800", x"839", x"873", x"8AC", x"8E4", x"91B", x"952", x"988", x"9BC", x"9EF", x"A21", x"A51", x"A7E", x"AAA", x"AD4", x"AFC", x"B21", x"B43", x"B63", x"B80", x"B9B", x"BB2", x"BC7", x"BD8", x"BE6", x"BF2", x"BFA", x"BFE", x"C00", x"BFE", x"BFA", x"BF2", x"BE6", x"BD8", x"BC7", x"BB2", x"B9B", x"B80", x"B63", x"B43", x"B21", x"AFC", x"AD4", x"AAA", x"A7E", x"A51", x"A21", x"9EF", x"9BC", x"988", x"952", x"91B", x"8E4", x"8AC", x"873", x"839", x"800", x"7C7", x"78D", x"754", x"71C", x"6E5", x"6AE", x"678", x"644", x"611", x"5DF", x"5AF", x"582", x"556", x"52C", x"504", x"4DF", x"4BD", x"49D", x"480", x"465", x"44E", x"439", x"428", x"41A", x"40E", x"406", x"402", x"400", x"402", x"406", x"40E", x"41A", x"428", x"439", x"44E", x"465", x"480", x"49D", x"4BD", x"4DF", x"504", x"52C", x"556", x"582", x"5AF", x"5DF", x"611", x"644", x"678", x"6AE", x"6E5", x"71C", x"754", x"78D", x"7C7", others => x"000"),
len => 112
);
-- ZERO: 2048, AMPLITUDE: 1551, FREQUENCY: 10kHz
constant sine3 : SIGNAL_RECORD_TYPE := (
sine => (x"800", x"857", x"8AE", x"904", x"959", x"9AD", x"A00", x"A52", x"AA1", x"AEE", x"B39", x"B82", x"BC7", x"C0A", x"C49", x"C84", x"CBD", x"CF1", x"D21", x"D4D", x"D75", x"D99", x"DB8", x"DD2", x"DE8", x"DF9", x"E05", x"E0D", x"E0F", x"E0D", x"E05", x"DF9", x"DE8", x"DD2", x"DB8", x"D99", x"D75", x"D4D", x"D21", x"CF1", x"CBD", x"C84", x"C49", x"C0A", x"BC7", x"B82", x"B39", x"AEE", x"AA1", x"A52", x"A00", x"9AD", x"959", x"904", x"8AE", x"857", x"800", x"7A9", x"752", x"6FC", x"6A7", x"653", x"600", x"5AE", x"55F", x"512", x"4C7", x"47E", x"439", x"3F6", x"3B7", x"37C", x"343", x"30F", x"2DF", x"2B3", x"28B", x"267", x"248", x"22E", x"218", x"207", x"1FB", x"1F3", x"1F1", x"1F3", x"1FB", x"207", x"218", x"22E", x"248", x"267", x"28B", x"2B3", x"2DF", x"30F", x"343", x"37C", x"3B7", x"3F6", x"439", x"47E", x"4C7", x"512", x"55F", x"5AE", x"600", x"653", x"6A7", x"6FC", x"752", x"7A9", others => x"000"),
len => 112
);
-- ZERO: 2048, AMPLITUDE: 2047, FREQUENCY: 20kHz
constant sine4 : SIGNAL_RECORD_TYPE := (
sine => (x"800", x"8E5", x"9C8", x"AA4", x"B78", x"C41", x"CFC", x"DA7", x"E40", x"EC5", x"F34", x"F8C", x"FCC", x"FF2", x"FFF", x"FF2", x"FCC", x"F8C", x"F34", x"EC5", x"E40", x"DA7", x"CFC", x"C41", x"B78", x"AA4", x"9C8", x"8E5", x"800", x"71B", x"638", x"55C", x"488", x"3BF", x"304", x"259", x"1C0", x"13B", x"0CC", x"074", x"034", x"00E", x"001", x"00E", x"034", x"074", x"0CC", x"13B", x"1C0", x"259", x"304", x"3BF", x"488", x"55C", x"638", x"71B", others => x"000"),
len => 56
);
-- ZERO: 2048, AMPLITUDE: 1024, FREQUENCY: 20kHz
constant sine5 : SIGNAL_RECORD_TYPE := (
sine => (x"800", x"873", x"8E4", x"952", x"9BC", x"A21", x"A7E", x"AD4", x"B21", x"B63", x"B9B", x"BC7", x"BE6", x"BFA", x"C00", x"BFA", x"BE6", x"BC7", x"B9B", x"B63", x"B21", x"AD4", x"A7E", x"A21", x"9BC", x"952", x"8E4", x"873", x"800", x"78D", x"71C", x"6AE", x"644", x"5DF", x"582", x"52C", x"4DF", x"49D", x"465", x"439", x"41A", x"406", x"400", x"406", x"41A", x"439", x"465", x"49D", x"4DF", x"52C", x"582", x"5DF", x"644", x"6AE", x"71C", x"78D", others => x"000"),
len => 56
);
-- ZERO: 2048, AMPLITUDE: 1551, FREQUENCY: 20kHz
constant sine6 : SIGNAL_RECORD_TYPE := (
sine => (x"800", x"8AE", x"959", x"A00", x"AA1", x"B39", x"BC7", x"C49", x"CBD", x"D21", x"D75", x"DB8", x"DE8", x"E05", x"E0F", x"E05", x"DE8", x"DB8", x"D75", x"D21", x"CBD", x"C49", x"BC7", x"B39", x"AA1", x"A00", x"959", x"8AE", x"800", x"752", x"6A7", x"600", x"55F", x"4C7", x"439", x"3B7", x"343", x"2DF", x"28B", x"248", x"218", x"1FB", x"1F1", x"1FB", x"218", x"248", x"28B", x"2DF", x"343", x"3B7", x"439", x"4C7", x"55F", x"600", x"6A7", x"752", others => x"000"),
len => 56
);
end package;

View File

@ -15,8 +15,8 @@ package typedef_package is
constant ADC_DELAY_CLK_CNT : integer := 2; constant ADC_DELAY_CLK_CNT : integer := 2;
constant DAC_TRANSFER_CLK_COUNT : integer := 16; constant DAC_TRANSFER_CLK_COUNT : integer := 16;
constant MAX_DELAY : integer := 1024; constant MAX_DELAY : integer := 65536;
constant DELAY_WIDTH : integer := 10; --at least log2(MAX_DELAY) constant DELAY_WIDTH : integer := 16; --at least log2(MAX_DELAY)
constant FACTOR_WIDTH : integer := 5; constant FACTOR_WIDTH : integer := 5;
constant TIMESTAMP_WIDTH : integer := 32; constant TIMESTAMP_WIDTH : integer := 32;

View File

@ -14,7 +14,7 @@ use work.typedef_package.all;
-- memory for configuration. The 32-bit wide 16-bit address interface is converted into 2 32-bit wide -- memory for configuration. The 32-bit wide 16-bit address interface is converted into 2 32-bit wide
-- 15-bit address RAMs, effectively increasing the internal config to 64-bits. -- 15-bit address RAMs, effectively increasing the internal config to 64-bits.
-- NOTE: It has to be made sure that the read and write port to not access the smae address at the same -- NOTE: It has to be made sure that the read and write port do not access the same address at the same
-- time -- time
entity xillybus_link is entity xillybus_link is

View File

@ -146,12 +146,6 @@
<Attr Name="UsedIn" Val="simulation"/> <Attr Name="UsedIn" Val="simulation"/>
</FileInfo> </FileInfo>
</File> </File>
<File Path="$PPRDIR/../../src/addsub.vhd">
<FileInfo SFType="VHDL2008">
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../src/typedef_package.vhd"> <File Path="$PPRDIR/../../src/typedef_package.vhd">
<FileInfo SFType="VHDL2008"> <FileInfo SFType="VHDL2008">
<Attr Name="UsedIn" Val="synthesis"/> <Attr Name="UsedIn" Val="synthesis"/>
@ -258,6 +252,7 @@
<Option Name="TopModule" Val="unknown"/> <Option Name="TopModule" Val="unknown"/>
<Option Name="TransportPathDelay" Val="0"/> <Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/> <Option Name="TransportIntDelay" Val="0"/>
<Option Name="SimMode" Val="post-implementation"/>
<Option Name="SrcSet" Val="sources_1"/> <Option Name="SrcSet" Val="sources_1"/>
<Option Name="xsim.simulate.runtime" Val="1000 ns"/> <Option Name="xsim.simulate.runtime" Val="1000 ns"/>
<Option Name="xsim.simulate.uut" Val="UUT"/> <Option Name="xsim.simulate.uut" Val="UUT"/>