* Route sclk for ADC/DAC through controller entity itself

* Remove ADC/DAC input/outputs constraints
* Fix PMOD-AS1 Controller
	- Invert SCLK
This commit is contained in:
Greek 2020-04-29 14:01:01 +02:00
parent 131a9b3a6e
commit 89182e8060
5 changed files with 103 additions and 82 deletions

View File

@ -24,12 +24,14 @@ entity feedback_loop is
port ( port (
clk : in std_logic; clk : in std_logic;
reset : in std_logic; reset : in std_logic;
adc_data_in1 : in std_logic; adc_data_in1 : in std_logic; -- PMOD-AD1
adc_data_in2 : in std_logic; adc_data_in2 : in std_logic; -- PMOD-AD1
adc_cs_n : out std_logic; adc_cs_n : out std_logic; -- PMOD-AD1
dac_data_out : out std_logic; adc_sclk : out std_logic; -- PMOD-AD1
dac_cs_n : out std_logic; dac_data_out : out std_logic; -- PMOD-DA3
dac_ldac : out std_logic; dac_cs_n : out std_logic; -- PMOD-DA3
dac_ldac : 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=ADC Input 2, 0=GND)
@ -58,11 +60,12 @@ architecture arch of feedback_loop is
DATA_WIDTH : integer := 12 DATA_WIDTH : integer := 12
); );
port ( port (
sclk : in std_logic; -- PMOD-AD1 clk : in std_logic;
reset : in std_logic; reset : in std_logic;
enable : in std_logic;
sdata1 : in std_logic; -- PMOD-AD1 sdata1 : in std_logic; -- PMOD-AD1
sdata2 : in std_logic; -- PMOD-AD1 sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic; sclk : out std_logic;-- PMOD-AD1
cs_n : out std_logic;-- PMOD-AD1 cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0); data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0); data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
@ -76,13 +79,14 @@ architecture arch of feedback_loop is
DATA_WIDTH : integer := 16 DATA_WIDTH : integer := 16
); );
port ( port (
sclk : in std_logic; -- PMOD-DA3 clk : in std_logic;
reset : in std_logic; reset : in std_logic;
start : in std_logic; start : in std_logic;
data : in std_logic_vector(DATA_WIDTH-1 downto 0); data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3 cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3 sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3 ldac : out std_logic;-- PMOD-DA3
sclk : out std_logic;-- PMOD-DA3
done : out std_logic done : out std_logic
); );
end component; end component;
@ -148,11 +152,12 @@ begin
DATA_WIDTH => ADC_DATA_WIDTH DATA_WIDTH => ADC_DATA_WIDTH
) )
port map( port map(
sclk => clk, clk => clk,
reset => reset, reset => reset,
enable => '1',
sdata1 => adc_data_in1, sdata1 => adc_data_in1,
sdata2 => adc_data_in2, sdata2 => adc_data_in2,
enable => '1', sclk => adc_sclk,
cs_n => adc_cs_n, cs_n => adc_cs_n,
data1 => adc_data1, data1 => adc_data1,
data2 => adc_data2, data2 => adc_data2,
@ -254,13 +259,14 @@ begin
DATA_WIDTH => DAC_DATA_WIDTH DATA_WIDTH => DAC_DATA_WIDTH
) )
port map( port map(
sclk => clk, clk => clk,
reset => reset, reset => reset,
start => addsub_done, start => addsub_done,
data => addsub_out, data => addsub_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,
sclk => dac_sclk,
done => open done => open
); );

View File

@ -66,12 +66,14 @@ architecture arch of feedback_top is
port ( port (
clk : in std_logic; clk : in std_logic;
reset : in std_logic; reset : in std_logic;
adc_data_in1 : in std_logic; adc_data_in1 : in std_logic; -- PMOD-AD1
adc_data_in2 : in std_logic; adc_data_in2 : in std_logic; -- PMOD-AD1
adc_cs_n : out std_logic; adc_cs_n : out std_logic; -- PMOD-AD1
dac_data_out : out std_logic; adc_sclk : out std_logic; -- PMOD-AD1
dac_cs_n : out std_logic; dac_data_out : out std_logic; -- PMOD-DA3
dac_ldac : out std_logic; dac_cs_n : out std_logic; -- PMOD-DA3
dac_ldac : 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=ADC Input 2, 0=GND)
@ -208,9 +210,11 @@ begin
adc_data_in1 => adc_data_in1, adc_data_in1 => adc_data_in1,
adc_data_in2 => adc_data_in2, adc_data_in2 => adc_data_in2,
adc_cs_n => adc_cs_n, adc_cs_n => adc_cs_n,
adc_sclk => adc_sclk,
dac_data_out => dac_data_out, dac_data_out => dac_data_out,
dac_cs_n => dac_cs_n, dac_cs_n => dac_cs_n,
dac_ldac => dac_ldac, dac_ldac => dac_ldac,
dac_sclk => dac_sclk,
addsub_mode => addsub_mode, addsub_mode => addsub_mode,
add_input_mux => add_input_mux, add_input_mux => add_input_mux,
delay => delay, delay => delay,
@ -259,9 +263,6 @@ begin
dac_max => dac_max dac_max => dac_max
); );
-- Connect ADC and DAC to FPGA clock
adc_sclk <= clk_20;
dac_sclk <= clk_20;
-- Connect standy to mem_full signal, to prevent simutanuoys read/writing on memory -- Connect standy to mem_full signal, to prevent simutanuoys read/writing on memory
mem_full <= not standby; mem_full <= not standby;
-- Connect leds -- Connect leds

View File

@ -5,10 +5,11 @@ use ieee.numeric_std.all;
-- Controller for the PMOD AD1 Digilent Board. -- Controller for the PMOD AD1 Digilent Board.
-- The controller keeps the AD7476A in "normal mode" throughout its operation, and as long as the enable -- The controller keeps the AD7476A in "normal mode" throughout its operation, and as long as the enable
-- signal is high, converts the ADC input signal at a rate of sclk_freq/(TRANSFER_CLK_COUNT+DELAY_CLK_CNT). -- signal is high, converts the ADC input signal at a rate of sclk_freq/(TRANSFER_CLK_COUNT+DELAY_CLK_CNT).
-- On conversion finish the done signal is pulsed high for a sclk cycle. The data outputs contain valid -- On conversion finish the done signal is pulsed high for a single clk cycle. The data outputs contain valid
-- data only when done is asserted. If enable is pulled low, the controller enters a standby mode and -- data only when done is asserted. If enable is pulled low, the controller enters a standby mode and
-- waits until the enable signal is pulled high again. If the enable is pulled low during a -- waits until the enable signal is pulled high again. If the enable is pulled low during a
-- converion/transfer, the conversion/transfer is completed before entering the idle mode. -- converion/transfer, the conversion/transfer is completed before entering the idle mode.
-- NOTE: The AD7476A supports a max clock frequency of 20 MHz
entity pmod_ad1_ctrl is entity pmod_ad1_ctrl is
generic( generic(
@ -17,11 +18,12 @@ entity pmod_ad1_ctrl is
DATA_WIDTH : integer := 12 DATA_WIDTH : integer := 12
); );
port ( port (
sclk : in std_logic; -- PMOD-AD1 clk : in std_logic;
reset : in std_logic; reset : in std_logic;
enable : in std_logic;
sdata1 : in std_logic; -- PMOD-AD1 sdata1 : in std_logic; -- PMOD-AD1
sdata2 : in std_logic; -- PMOD-AD1 sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic; sclk : out std_logic;-- PMOD-AD1
cs_n : out std_logic;-- PMOD-AD1 cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0); data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0); data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
@ -91,8 +93,12 @@ begin
end case; end case;
end process; end process;
sync : process(sclk, reset) --Connect SCLK (Inverted)
sclk <= not clk;
sync : process(clk)
begin begin
if (rising_edge(clk)) then
if (reset = '1') then if (reset = '1') then
-- Internal Signals -- Internal Signals
buf1 <= (others => '0'); buf1 <= (others => '0');
@ -104,7 +110,7 @@ begin
data1 <= (others => '0'); data1 <= (others => '0');
data2 <= (others => '0'); data2 <= (others => '0');
done <= '0'; done <= '0';
elsif (rising_edge(sclk)) then else
-- Internal Signals -- Internal Signals
buf1 <= buf1_next; buf1 <= buf1_next;
buf2 <= buf2_next; buf2 <= buf2_next;
@ -116,6 +122,7 @@ begin
data2 <= buf2_next; data2 <= buf2_next;
done <= done_next; done <= done_next;
end if; end if;
end if;
end process; end process;
end architecture; end architecture;

View File

@ -5,9 +5,10 @@ use ieee.numeric_std.all;
-- Controller for the PMOD DA3 Digilent Board. -- Controller for the PMOD DA3 Digilent Board.
-- The controller sends the input 'data' word to the DAC when 'start' is asserted. The 'data' input has -- The controller sends the input 'data' word to the DAC when 'start' is asserted. The 'data' input has
-- to be valid only during the period 'start' is asserted, as for the transfer the word is latched -- to be valid only during the period 'start' is asserted, as for the transfer the word is latched
-- internally. When the transfer is done, the 'done' signal is asserted for one clock cycle. The 'start' -- internally. When the transfer is done, the 'done' signal is asserted for a single clock cycle. The 'start'
-- and 'done' cycle can be high at the same time, allowing the done signal to be asynchronously connected -- and 'done' cycle can be high at the same time, allowing the done signal to be asynchronously connected
-- to the 'start' signal to save on latency. -- to the 'start' signal to save on latency.
-- NOTE: The AD5541A supports a maximum clk frequency of 50 MHz
entity pmod_da3_ctrl is entity pmod_da3_ctrl is
@ -16,13 +17,14 @@ entity pmod_da3_ctrl is
DATA_WIDTH : integer := 16 DATA_WIDTH : integer := 16
); );
port ( port (
sclk : in std_logic; -- PMOD-DA3 clk : in std_logic;
reset : in std_logic; reset : in std_logic;
start : in std_logic; start : in std_logic;
data : in std_logic_vector(DATA_WIDTH-1 downto 0); data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3 cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3 sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3 ldac : out std_logic;-- PMOD-DA3
sclk : out std_logic;-- PMOD-DA3
done : out std_logic done : out std_logic
); );
end entity; end entity;
@ -81,8 +83,12 @@ begin
end case; end case;
end process; end process;
sync : process(sclk, reset) --Connect SCLK
sclk <= clk;
sync : process(clk)
begin begin
if (rising_edge(sclk)) then
if (reset = '1') then if (reset = '1') then
-- Internal Signals -- Internal Signals
buf <= (others => '0'); buf <= (others => '0');
@ -92,7 +98,7 @@ begin
cs_n <= '1'; cs_n <= '1';
sdata <= '0'; sdata <= '0';
done <= '0'; done <= '0';
elsif (rising_edge(sclk)) then else
-- Internal Signals -- Internal Signals
buf <= buf_next; buf <= buf_next;
stage <= stage_next; stage <= stage_next;
@ -102,6 +108,7 @@ begin
sdata <= sdata_next; sdata <= sdata_next;
done <= done_next; done <= done_next;
end if; end if;
end if;
end process; end process;
end architecture; end architecture;

View File

@ -51,17 +51,17 @@ set_property -dict {PACKAGE_PIN AB2 IOSTANDARD LVCMOS33} [get_ports audio_mclk]
create_clock -period 100.000 -name sys_clk -waveform {0.000 50.000} [get_ports clk_ext] create_clock -period 100.000 -name sys_clk -waveform {0.000 50.000} [get_ports clk_ext]
create_clock -period 50.000 -name VIRTUAL_dac_sclk_OBUF -waveform {0.000 25.000} #create_clock -period 50.000 -name VIRTUAL_dac_sclk_OBUF -waveform {0.000 25.000}
set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -min -add_delay -10.000 [get_ports adc_data_in1] #set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -min -add_delay -10.000 [get_ports adc_data_in1]
set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -max -add_delay 10.000 [get_ports adc_data_in1] #set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -max -add_delay 10.000 [get_ports adc_data_in1]
set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -min -add_delay -10.000 [get_ports adc_data_in2] #set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -min -add_delay -10.000 [get_ports adc_data_in2]
set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -max -add_delay 10.000 [get_ports adc_data_in2] #set_input_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -max -add_delay 10.000 [get_ports adc_data_in2]
set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -min -add_delay -5.000 [get_ports adc_cs_n] #set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -min -add_delay -5.000 [get_ports adc_cs_n]
set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -max -add_delay 10.000 [get_ports adc_cs_n] #set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -clock_fall -max -add_delay 10.000 [get_ports adc_cs_n]
set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -min -add_delay -5.000 [get_ports dac_cs_n] #set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -min -add_delay -5.000 [get_ports dac_cs_n]
set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -max -add_delay 5.000 [get_ports dac_cs_n] #set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -max -add_delay 5.000 [get_ports dac_cs_n]
set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -min -add_delay -5.000 [get_ports dac_data_out] #set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -min -add_delay -5.000 [get_ports dac_data_out]
set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -max -add_delay 10.000 [get_ports dac_data_out] #set_output_delay -clock [get_clocks VIRTUAL_dac_sclk_OBUF] -max -add_delay 10.000 [get_ports dac_data_out]
set_property IOSTANDARD LVCMOS33 [get_ports adc_cs_n] set_property IOSTANDARD LVCMOS33 [get_ports adc_cs_n]
set_property IOSTANDARD LVCMOS33 [get_ports adc_data_in1] set_property IOSTANDARD LVCMOS33 [get_ports adc_data_in1]