diff --git a/src/feedback_loop.vhd b/src/feedback_loop.vhd index a2efa29..d164c7b 100644 --- a/src/feedback_loop.vhd +++ b/src/feedback_loop.vhd @@ -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 ); diff --git a/src/feedback_top.vhd b/src/feedback_top.vhd index 0db9a5c..4909dcc 100644 --- a/src/feedback_top.vhd +++ b/src/feedback_top.vhd @@ -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, @@ -258,10 +262,7 @@ begin scaler_max => scaler_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 mem_full <= not standby; -- Connect leds diff --git a/src/pmod_ad1_ctrl.vhd b/src/pmod_ad1_ctrl.vhd index e04a348..e39619e 100644 --- a/src/pmod_ad1_ctrl.vhd +++ b/src/pmod_ad1_ctrl.vhd @@ -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); @@ -90,31 +92,36 @@ begin end if; end case; end process; - - sync : process(sclk, reset) + + --Connect SCLK (Inverted) + sclk <= not clk; + + sync : process(clk) begin - if (reset = '1') then - -- Internal Signals - buf1 <= (others => '0'); - buf2 <= (others => '0'); - stage <= IDLE; - count <= 0; - -- Output Signals - cs_n <= '1'; - data1 <= (others => '0'); - data2 <= (others => '0'); - done <= '0'; - elsif (rising_edge(sclk)) then - -- Internal Signals - buf1 <= buf1_next; - buf2 <= buf2_next; - stage <= stage_next; - count <= count_next; - -- Output Signals - cs_n <= cs_n_next; - data1 <= buf1_next; - data2 <= buf2_next; - done <= done_next; + if (rising_edge(clk)) then + if (reset = '1') then + -- Internal Signals + buf1 <= (others => '0'); + buf2 <= (others => '0'); + stage <= IDLE; + count <= 0; + -- Output Signals + cs_n <= '1'; + data1 <= (others => '0'); + data2 <= (others => '0'); + done <= '0'; + else + -- Internal Signals + buf1 <= buf1_next; + buf2 <= buf2_next; + stage <= stage_next; + count <= count_next; + -- Output Signals + cs_n <= cs_n_next; + data1 <= buf1_next; + data2 <= buf2_next; + done <= done_next; + end if; end if; end process; diff --git a/src/pmod_da3_ctrl.vhd b/src/pmod_da3_ctrl.vhd index decf674..c1a3b3c 100644 --- a/src/pmod_da3_ctrl.vhd +++ b/src/pmod_da3_ctrl.vhd @@ -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; @@ -80,27 +82,32 @@ begin end if; end case; end process; - - sync : process(sclk, reset) + + --Connect SCLK + sclk <= clk; + + sync : process(clk) begin - if (reset = '1') then - -- Internal Signals - buf <= (others => '0'); - stage <= IDLE; - count <= 0; - -- Output Signals - cs_n <= '1'; - sdata <= '0'; - done <= '0'; - elsif (rising_edge(sclk)) then - -- Internal Signals - buf <= buf_next; - stage <= stage_next; - count <= count_next; - -- Output Signals - cs_n <= cs_n_next; - sdata <= sdata_next; - done <= done_next; + if (rising_edge(sclk)) then + if (reset = '1') then + -- Internal Signals + buf <= (others => '0'); + stage <= IDLE; + count <= 0; + -- Output Signals + cs_n <= '1'; + sdata <= '0'; + done <= '0'; + else + -- Internal Signals + buf <= buf_next; + stage <= stage_next; + count <= count_next; + -- Output Signals + cs_n <= cs_n_next; + sdata <= sdata_next; + done <= done_next; + end if; end if; end process; diff --git a/xillinux-syn/vivado-essentials/xillydemo.xdc b/xillinux-syn/vivado-essentials/xillydemo.xdc index 2c36a8b..924a4c7 100644 --- a/xillinux-syn/vivado-essentials/xillydemo.xdc +++ b/xillinux-syn/vivado-essentials/xillydemo.xdc @@ -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]