diff --git a/.gitignore b/.gitignore
index eba538a..756ae22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
#Ignore List
/syn/**
/modelsim/**
+/ip/**
#Unignore Directories (Needed to unignore files in Subdirectories)
diff --git a/doc/ug573-ultrascale-memory-resources.pdf b/doc/ug573-ultrascale-memory-resources.pdf
new file mode 100644
index 0000000..bc241c5
--- /dev/null
+++ b/doc/ug573-ultrascale-memory-resources.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:703916371dafe6dddfd0c4b75c15e13a1f6b998c85ee38c1af2e05213807a70b
+size 3838985
diff --git a/doc/ug974-vivado-ultrascale-libraries.pdf b/doc/ug974-vivado-ultrascale-libraries.pdf
new file mode 100644
index 0000000..fd58dd1
--- /dev/null
+++ b/doc/ug974-vivado-ultrascale-libraries.pdf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67bc73fa17fc19acb51a5bd9ce50237703f1aad7c1b64227015de9b402f456ab
+size 5980850
diff --git a/src/addsub.vhd b/src/addsub.vhd
new file mode 100644
index 0000000..ab608c9
--- /dev/null
+++ b/src/addsub.vhd
@@ -0,0 +1,75 @@
+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).
+-- NOTE: In 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 : std_logic;
+ reset : std_logic;
+ mode : std_logic;
+ A : std_logic_vector(DATA_WIDTH-1 downto 0);
+ B : std_logic_vector(DATA_WIDTH-1 downto 0);
+ RES : 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') 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;
\ No newline at end of file
diff --git a/src/delay_line.vhd b/src/delay_line.vhd
new file mode 100644
index 0000000..9f4bc67
--- /dev/null
+++ b/src/delay_line.vhd
@@ -0,0 +1,100 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Variable Size Delay Line
+-- This entity is based on a single port RAM from which every clock cycle the old contents of an address
+-- are read out and updated with new contents. By incrementing the addresses in a pre-defined loop we
+-- have effectively a ring buffer that we can vary in size (up to the maximum capacity of the memory).
+-- NOTE: Changing the 'delay' value may lead to glitches during the first "delay period", due to the
+-- way the address generation is made. More specifically, these glitches happen when the 'delay' is
+-- increased (which is unavoidable), and when it is decreased while the counter is the same as the new
+-- delay [single cycle glitch].
+
+entity delay_line is
+ generic (
+ DATA_WIDTH : integer := 12;
+ DELAY_WIDTH : integer := 8;
+ MAX_DELAY : integer := 200
+ );
+ port (
+ clk : in std_logic;
+ delay : in std_logic_vector(DELAY_WIDTH-1 downto 0);
+ data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
+ );
+end entity;
+
+architecture arch of delay_line is
+
+ --*****COMPONENT DECLARATION*****
+ component single_port_ram is
+ generic (
+ ADDR_WIDTH : integer := 8;
+ DATA_WIDTH : integer := 12;
+ MEMORY_DEPTH : integer := 200
+ );
+ port (
+ clk : in std_logic;
+ addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
+ wen : in std_logic;
+ ren : in std_logic;
+ write_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ read_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
+ );
+ end component;
+
+ --*****SIGNAl DECLARATION*****
+ signal cnt, cnt_next, cnt_max, cnt_max_next : integer range 0 to MAX_DELAY := 0;
+ signal memory_out : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
+
+begin
+
+ --*****COMPONENT INSTANTIATION*****
+ ram_inst : single_port_ram
+ generic map(
+ ADDR_WIDTH => DELAY_WIDTH,
+ DATA_WIDTH => DATA_WIDTH,
+ MEMORY_DEPTH => MAX_DELAY
+ );
+ port map(
+ clk => clk,
+ addr => cnt,
+ wen => '1',
+ ren => '1',
+ write_data => data_in,
+ read_data => memory_out
+ );
+
+ cntrl : process(all)
+ begin
+ -- DEFAULT VALUES
+ cnt_next <= cnt;
+ cnt_max_next <= cnt_max;
+
+ if(to_integer(unsigned(addr)) = 0) then
+ data_out <= data_in;
+ else
+ data_out <= memory_out;
+ -- COUNT GENERATION
+ cnt_max_next <= to_integer(unsigned(addr)) - 1;
+ if (cnt >= cnt_max) then
+ cnt_next <= 0;
+ else
+ cnt_next <= cnt + 1;
+ end if;
+ end if;
+ end process;
+
+ sync : process(clk, reset)
+ begin
+ if (reset = '1') then
+ cnt <= 0;
+ cnt_max <= 0;
+ elsif(rising_edge(clk)) then
+ cnt <= cnt_next;
+ cnt_max <= cnt_max_next;
+ end if;
+ end process;
+
+end architecture;
\ No newline at end of file
diff --git a/src/feedback_loop.vhd b/src/feedback_loop.vhd
new file mode 100644
index 0000000..3602cb1
--- /dev/null
+++ b/src/feedback_loop.vhd
@@ -0,0 +1,235 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Architecture
+ --- ---------- ------ ------- ---
+--->|ADC|--->|Delay Line|--->|Scaler|--->|ADD/SUB|--->|DAC|--->
+ --- ---------- ------ ------- ---
+-- ^
+ --- ----- |
+--->|ADC|---------------------|Latch|--------
+ --- -----
+
+entity feedback_loop is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ adc_data_in1 : in std_logic;
+ adc_data_in2 : in std_logic;
+ addsub_mode : in std_logic;
+ delay : in std_logic_vector(7 downto 0);
+ factor : in std_logic_vector(3 downto 0);
+ adc_cs_n : out std_logic;
+ dac_data_out : out std_logic;
+ dac_cs_n : out std_logic;
+ dac_ldac : out std_logic
+ );
+end entity;
+
+architecture arch of feedback_loop is
+
+ --*****SIGNAL DECLARATION*****
+ signal adc_data1, adc_data2 : std_logic_vector(11 downto 0) := (others => '0');
+ signal adc_done : std_logic := '0';
+
+ --*****COMPONENT DECLARATION*****
+ component pmod_ad1_ctrl is
+ generic(
+ TRANSFER_CLK_COUNT : integer := 16;
+ DELAY_CLK_CNT : integer := 2;
+ DATA_BITS : integer := 12
+ );
+ port (
+ sclk : in std_logic; -- PMOD-AD1
+ reset : in std_logic;
+ sdata1 : in std_logic; -- PMOD-AD1
+ sdata2 : in std_logic; -- PMOD-AD1
+ enable : in std_logic;
+ cs_n : out std_logic;-- PMOD-AD1
+ data1 : out std_logic_vector(DATA_BITS-1 downto 0);
+ data2 : out std_logic_vector(DATA_BITS-1 downto 0);
+ done : out std_logic
+ );
+ end component;
+
+ component pmod_da3_ctrl is
+ generic(
+ TRANSFER_CLK_COUNT : integer := 16;
+ DATA_BITS : integer := 16
+ );
+ port (
+ sclk : in std_logic; -- PMOD-DA3
+ reset : in std_logic;
+ start : in std_logic;
+ data : in std_logic_vector(DATA_BITS-1 downto 0);
+ cs_n : out std_logic;-- PMOD-DA3
+ sdata : out std_logic;-- PMOD-DA3
+ ldac : out std_logic;-- PMOD-DA3
+ done : out std_logic
+ );
+ end component;
+
+ component scaler is
+ generic (
+ DATA_WIDTH : integer := 12;
+ FACTOR_WIDTH : integer := 4;
+ PIPELINE_STAGES : integer := 1
+ );
+ port (
+ clk : in std_logic;
+ data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0);
+ data_out : out std_logic_vector(DATA_WIDTH+FACTOR_WIDTH-1 downto 0)
+ );
+ end component;
+
+ component addsub is
+ generic (
+ PIPELINE_STAGES : integer := 1;
+ DATA_WIDTH : integer := 16
+ );
+ port (
+ clk : std_logic;
+ reset : std_logic;
+ mode : std_logic;
+ A : std_logic_vector(DATA_WIDTH-1 downto 0);
+ B : std_logic_vector(DATA_WIDTH-1 downto 0);
+ RES : std_logic_vector(DATA_WIDTH-1 downto 0)
+ );
+ end component;
+
+ component delay_line is
+ generic (
+ DATA_WIDTH : integer := 12;
+ DELAY_WIDTH : integer := 8;
+ MAX_DELAY : integer := 200
+ );
+ port (
+ clk : in std_logic;
+ delay : in std_logic_vector(DELAY_WIDTH-1 downto 0);
+ data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
+ );
+ end component;
+
+ --*****SIGNAL DECLARATION*****
+ signal delay_out, latch_out : std_logic_vector(12 downto 0) := (others => '0');
+ signal scaler_out, addsub_out : std_logic_vector(15 downto 0) := (others => '0');
+ signal scaler_done, addsub_done : std_logic := '0';
+
+begin
+
+ --*****STAGE I*****
+ adc_inst : pmod_ad1_ctrl
+ generic map(
+ TRANSFER_CLK_COUNT => 16,
+ DELAY_CLK_CNT => 2,
+ DATA_BITS => 12
+ )
+ port map(
+ sclk => clk,
+ reset => areset,
+ sdata1 => adc_data_in1,
+ sdata2 => adc_data_in2,
+ enable => '1',
+ cs_n => adc_cs_n,
+ data1 => adc_data1,
+ data2 => adc_data2,
+ done => adc_done
+ );
+
+ --*****STAGE II*****
+ delay_line_inst : delay_line
+ generic map(
+ DATA_WIDTH => 13,
+ DELAY_WIDTH => 8,
+ MAX_DELAY => 200
+ )
+ port map(
+ clk => clk,
+ delay => delay,
+ data_in => (adc_done & adc_data1),
+ data_out => delay_out
+ );
+
+ --*****STAGE III*****
+ scaler_inst : scaler
+ generic map(
+ DATA_WIDTH => 12,
+ FACTOR_WIDTH => 4,
+ PIPELINE_STAGES => 1
+ )
+ port map(
+ clk => clk,
+ data_in => delay_out(11 downto 0),
+ factor => factor,
+ data_out => scaler_out
+ );
+
+ process(clk)
+ begin
+ if (rising_edge(clk)) then
+ if (reset = '1') then
+ scaler_done <= (others => '0');
+ else
+ scaler_done <= delay_out(12);
+ end if;
+ end if;
+ end process;
+
+ latch : process(clk)
+ begin
+ if (rising_edge(clk)) then
+ if (reset = '1') then
+ latch_out <= (others => '0');
+ elsif (adc_done) then
+ latch_out <= adc_data2;
+ end if;
+ end if;
+ end process;
+
+ --*****STAGE IV*****
+ addsub_inst : addsub
+ generic map(
+ PIPELINE_STAGES => 1,
+ DATA_WIDTH => 16
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ mode => addsub_mode,
+ A => scaler_out,
+ B => latch_out & "0000",
+ RES => addsub_out
+ );
+
+ process(clk)
+ begin
+ if (rising_edge(clk)) then
+ if (reset = '1') then
+ addsub_done <= '0';
+ else
+ addsub_done <= scaler_done;
+ end if;
+ end if;
+ end process;
+
+ --*****STAGE V*****
+ dac_inst : pmod_da3_ctrl
+ generic map(
+ TRANSFER_CLK_COUNT => 16,
+ DATA_BITS => 16
+ )
+ port map(
+ sclk => clk,
+ reset => reset,
+ start => addsub_done,
+ data => addsub_out,
+ cs_n => dac_cs_n,
+ sdata => dac_data_out,
+ ldac => dac_ldac,
+ done => open
+ );
+
+end architecture;
\ No newline at end of file
diff --git a/src/mult.vhd b/src/mult.vhd
new file mode 100644
index 0000000..41665a9
--- /dev/null
+++ b/src/mult.vhd
@@ -0,0 +1,45 @@
+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;
+
+entity mult is
+ generic (
+ A_WIDTH : integer := 12;
+ B_WIDTH : integer := 4;
+ PIPELINE_STAGES : integer := 1
+ );
+ port (
+ clk : in std_logic;
+ A : in std_logic_vector(A_WIDTH-1 downto 0);
+ B : in std_logic_vector(B_WIDTH-1 downto 0);
+ P : out std_logic_vector(A_WIDTH+B_WIDTH-1 downto 0)
+ );
+end entity;
+
+architecture arch of mult is
+
+
+begin
+
+ MULT_MACRO_inst : MULT_MACRO
+ generic map (
+ DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "7SERIES", "SPARTAN6"
+ LATENCY => PIPELINE_STAGES, -- Desired clock cycle latency, 0-4
+ WIDTH_A => A_WIDTH, -- Multiplier A-input bus width, 1-25
+ WIDTH_B => B_WIDTH) -- Multiplier B-input bus width, 1-18
+ port map (
+ P => P, -- Multiplier ouput bus, width determined by WIDTH_P generic
+ A => A, -- Multiplier input A bus, width determined by WIDTH_A generic
+ B => B, -- Multiplier input B bus, width determined by WIDTH_B generic
+ CE => '1', -- 1-bit active high input clock enable
+ CLK => clk, -- 1-bit positive edge clock input
+ RST => '0' -- 1-bit input active high reset
+ );
+
+end architecture;
\ No newline at end of file
diff --git a/src/scaler.vhd b/src/scaler.vhd
new file mode 100644
index 0000000..79fcff4
--- /dev/null
+++ b/src/scaler.vhd
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Scaler
+-- This entity scales the 'data_in' input by the factor 'factor'.
+
+entity scaler is
+ generic (
+ DATA_WIDTH : integer := 12;
+ FACTOR_WIDTH : integer := 4;
+ PIPELINE_STAGES : integer := 1
+ );
+ port (
+ clk : in std_logic;
+ data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0);
+ data_out : out std_logic_vector(DATA_WIDTH+FACTOR_WIDTH-1 downto 0)
+ );
+end entity;
+
+architecture arch of scaler is
+
+ --*****COMPONENT DECLARATION*****
+ component mult is
+ generic (
+ A_WIDTH : integer := 12;
+ B_WIDTH : integer := 4;
+ PIPELINE_STAGES : integer := 1
+ );
+ port (
+ clk : in std_logic;
+ A : in std_logic_vector(A_WIDTH-1 downto 0);
+ B : in std_logic_vector(B_WIDTH-1 downto 0);
+ P : out std_logic_vector(A_WIDTH+B_WIDTH-1 downto 0)
+ );
+ end component;
+
+begin
+
+ mult_inst : mult
+ generic map(
+ A_WIDTH => DATA_WIDTH,
+ B_WIDTH => FACTOR_WIDTH,
+ PIPELINE_STAGES => PIPELINE_STAGES
+ );
+ port (
+ clk => clk,
+ A => data_in,
+ B => factor,
+ P => data_out
+ );
+
+end architecture;
\ No newline at end of file
diff --git a/src/single_port_ram.vhd b/src/single_port_ram.vhd
new file mode 100644
index 0000000..85dc69c
--- /dev/null
+++ b/src/single_port_ram.vhd
@@ -0,0 +1,65 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+Library xpm;
+use xpm.vcomponents.all;
+
+entity single_port_ram is
+ generic (
+ ADDR_WIDTH : integer := 8;
+ DATA_WIDTH : integer := 12;
+ MEMORY_DEPTH : integer := 200
+ );
+ port (
+ clk : in std_logic;
+ addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
+ wen : in std_logic;
+ ren : in std_logic;
+ write_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ read_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
+ );
+end entity;
+
+architecture arch of single_port_ram is
+
+begin
+
+ xpm_memory_spram_inst : xpm_memory_spram
+ generic map (
+ ADDR_WIDTH_A => ADDR_WIDTH,
+ AUTO_SLEEP_TIME => 0,
+ BYTE_WRITE_WIDTH_A => DATA_WIDTH,
+ ECC_MODE => "no_ecc",
+ MEMORY_INIT_FILE => "none",
+ MEMORY_INIT_PARAM => "0",
+ MEMORY_OPTIMIZATION => "true",
+ MEMORY_PRIMITIVE => "auto",
+ MEMORY_SIZE => DATA_WIDTH*MEMORY_DEPTH,
+ MESSAGE_CONTROL => 0,
+ READ_DATA_WIDTH_A => DATA_WIDTH,
+ READ_LATENCY_A => 1,
+ READ_RESET_VALUE_A => "0",
+ RST_MODE_A => "SYNC",
+ USE_MEM_INIT => 1,
+ WAKEUP_TIME => "disable_sleep",
+ WRITE_DATA_WIDTH_A => DATA_WIDTH,
+ WRITE_MODE_A => "read_first"
+ )
+ port map (
+ dbiterra => open,
+ douta => read_data,
+ sbiterra => open,
+ addra => addr,
+ clka => clk,
+ dina => write_data,
+ ena => (ren or wen),
+ injectdbiterra => '0',
+ injectsbiterra => '0',
+ regcea => '1',
+ rsta => '0',
+ sleep => '0',
+ wea => wen
+ );
+
+end architecture;
\ No newline at end of file
diff --git a/syn/labor-mst.xpr b/syn/labor-mst.xpr
index 46e35cf..07753bb 100644
--- a/syn/labor-mst.xpr
+++ b/syn/labor-mst.xpr
@@ -41,13 +41,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+