* Add library/macro relevant documentation

* Implemented closed feedback loop
	- Scaler
	- Dealy Line
	- Add Sub
This commit is contained in:
Greek 2020-04-03 17:50:25 +02:00
parent e1ffa99874
commit 7392d9f72f
10 changed files with 588 additions and 7 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
#Ignore List
/syn/**
/modelsim/**
/ip/**
#Unignore Directories (Needed to unignore files in Subdirectories)

BIN
doc/ug573-ultrascale-memory-resources.pdf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
doc/ug974-vivado-ultrascale-libraries.pdf (Stored with Git LFS) Normal file

Binary file not shown.

75
src/addsub.vhd Normal file
View File

@ -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;

100
src/delay_line.vhd Normal file
View File

@ -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;

235
src/feedback_loop.vhd Normal file
View File

@ -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;

45
src/mult.vhd Normal file
View File

@ -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;

54
src/scaler.vhd Normal file
View File

@ -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;

65
src/single_port_ram.vhd Normal file
View File

@ -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;

View File

@ -41,13 +41,13 @@
<Option Name="WTVcsLaunchSim" Val="0"/>
<Option Name="WTRivieraLaunchSim" Val="0"/>
<Option Name="WTActivehdlLaunchSim" Val="0"/>
<Option Name="WTXSimExportSim" Val="2"/>
<Option Name="WTModelSimExportSim" Val="2"/>
<Option Name="WTQuestaExportSim" Val="2"/>
<Option Name="WTIesExportSim" Val="2"/>
<Option Name="WTVcsExportSim" Val="2"/>
<Option Name="WTRivieraExportSim" Val="2"/>
<Option Name="WTActivehdlExportSim" Val="2"/>
<Option Name="WTXSimExportSim" Val="3"/>
<Option Name="WTModelSimExportSim" Val="3"/>
<Option Name="WTQuestaExportSim" Val="3"/>
<Option Name="WTIesExportSim" Val="3"/>
<Option Name="WTVcsExportSim" Val="3"/>
<Option Name="WTRivieraExportSim" Val="3"/>
<Option Name="WTActivehdlExportSim" Val="3"/>
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
<Option Name="XSimRadix" Val="hex"/>
<Option Name="XSimTimeUnit" Val="ns"/>