* 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 (
clk : in std_logic;
reset : in std_logic;
adc_data_in1 : in std_logic;
adc_data_in2 : in std_logic;
adc_cs_n : out std_logic;
dac_data_out : out std_logic;
dac_cs_n : out std_logic;
dac_ldac : out std_logic;
adc_data_in1 : in std_logic; -- PMOD-AD1
adc_data_in2 : in std_logic; -- PMOD-AD1
adc_cs_n : out std_logic; -- PMOD-AD1
adc_sclk : out std_logic; -- PMOD-AD1
dac_data_out : out std_logic; -- PMOD-DA3
dac_cs_n : out std_logic; -- PMOD-DA3
dac_ldac : out std_logic; -- PMOD-DA3
dac_sclk : out std_logic; -- PMOD-DA3
-- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
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
);
port (
sclk : in std_logic; -- PMOD-AD1
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
sdata1 : 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
data1 : 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
);
port (
sclk : in std_logic; -- PMOD-DA3
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3
sclk : out std_logic;-- PMOD-DA3
done : out std_logic
);
end component;
@ -148,11 +152,12 @@ begin
DATA_WIDTH => ADC_DATA_WIDTH
)
port map(
sclk => clk,
clk => clk,
reset => reset,
enable => '1',
sdata1 => adc_data_in1,
sdata2 => adc_data_in2,
enable => '1',
sclk => adc_sclk,
cs_n => adc_cs_n,
data1 => adc_data1,
data2 => adc_data2,
@ -254,13 +259,14 @@ begin
DATA_WIDTH => DAC_DATA_WIDTH
)
port map(
sclk => clk,
clk => clk,
reset => reset,
start => addsub_done,
data => addsub_out,
cs_n => dac_cs_n,
sdata => dac_data_out,
ldac => dac_ldac,
sclk => dac_sclk,
done => open
);

View File

@ -66,12 +66,14 @@ architecture arch of feedback_top is
port (
clk : in std_logic;
reset : in std_logic;
adc_data_in1 : in std_logic;
adc_data_in2 : in std_logic;
adc_cs_n : out std_logic;
dac_data_out : out std_logic;
dac_cs_n : out std_logic;
dac_ldac : out std_logic;
adc_data_in1 : in std_logic; -- PMOD-AD1
adc_data_in2 : in std_logic; -- PMOD-AD1
adc_cs_n : out std_logic; -- PMOD-AD1
adc_sclk : out std_logic; -- PMOD-AD1
dac_data_out : out std_logic; -- PMOD-DA3
dac_cs_n : out std_logic; -- PMOD-DA3
dac_ldac : out std_logic; -- PMOD-DA3
dac_sclk : out std_logic; -- PMOD-DA3
-- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
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_in2 => adc_data_in2,
adc_cs_n => adc_cs_n,
adc_sclk => adc_sclk,
dac_data_out => dac_data_out,
dac_cs_n => dac_cs_n,
dac_ldac => dac_ldac,
dac_sclk => dac_sclk,
addsub_mode => addsub_mode,
add_input_mux => add_input_mux,
delay => delay,
@ -259,9 +263,6 @@ begin
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
mem_full <= not standby;
-- Connect leds

View File

@ -5,10 +5,11 @@ use ieee.numeric_std.all;
-- Controller for the PMOD AD1 Digilent Board.
-- 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).
-- 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
-- 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.
-- NOTE: The AD7476A supports a max clock frequency of 20 MHz
entity pmod_ad1_ctrl is
generic(
@ -17,11 +18,12 @@ entity pmod_ad1_ctrl is
DATA_WIDTH : integer := 12
);
port (
sclk : in std_logic; -- PMOD-AD1
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
sdata1 : 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
data1 : 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 process;
sync : process(sclk, reset)
--Connect SCLK (Inverted)
sclk <= not clk;
sync : process(clk)
begin
if (rising_edge(clk)) then
if (reset = '1') then
-- Internal Signals
buf1 <= (others => '0');
@ -104,7 +110,7 @@ begin
data1 <= (others => '0');
data2 <= (others => '0');
done <= '0';
elsif (rising_edge(sclk)) then
else
-- Internal Signals
buf1 <= buf1_next;
buf2 <= buf2_next;
@ -116,6 +122,7 @@ begin
data2 <= buf2_next;
done <= done_next;
end if;
end if;
end process;
end architecture;

View File

@ -5,9 +5,10 @@ use ieee.numeric_std.all;
-- 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
-- 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
-- to the 'start' signal to save on latency.
-- NOTE: The AD5541A supports a maximum clk frequency of 50 MHz
entity pmod_da3_ctrl is
@ -16,13 +17,14 @@ entity pmod_da3_ctrl is
DATA_WIDTH : integer := 16
);
port (
sclk : in std_logic; -- PMOD-DA3
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3
sclk : out std_logic;-- PMOD-DA3
done : out std_logic
);
end entity;
@ -81,8 +83,12 @@ begin
end case;
end process;
sync : process(sclk, reset)
--Connect SCLK
sclk <= clk;
sync : process(clk)
begin
if (rising_edge(sclk)) then
if (reset = '1') then
-- Internal Signals
buf <= (others => '0');
@ -92,7 +98,7 @@ begin
cs_n <= '1';
sdata <= '0';
done <= '0';
elsif (rising_edge(sclk)) then
else
-- Internal Signals
buf <= buf_next;
stage <= stage_next;
@ -102,6 +108,7 @@ begin
sdata <= sdata_next;
done <= done_next;
end if;
end if;
end process;
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 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 -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 -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 -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] -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] -max -add_delay 10.000 [get_ports dac_data_out]
#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 -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 -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 -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] -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] -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_data_in1]