From 024261c4d40acf9b87943de53ce26dbbd9bcb33b Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Tue, 22 Jul 2014 14:05:03 +0200 Subject: [PATCH] next step towards running ADC board --- ADC/trb3_periph_adc.prj | 2 +- ADC/trb3_periph_adc.vhd | 50 +++++++++++++-- base/code/adc_ad9219.vhd | 110 +++++++++++++++++++++++++++++--- base/code/adc_data_buffer.vhd | 117 ++++++++++++++++++++++++++++++++++ base/trb3_periph_adc.lpf | 2 +- 5 files changed, 264 insertions(+), 17 deletions(-) create mode 100644 base/code/adc_data_buffer.vhd diff --git a/ADC/trb3_periph_adc.prj b/ADC/trb3_periph_adc.prj index 620e912..fd3b8df 100644 --- a/ADC/trb3_periph_adc.prj +++ b/ADC/trb3_periph_adc.prj @@ -146,6 +146,6 @@ add_file -vhdl -lib "work" "../base/cores/dqsinput_7x5.vhd" add_file -vhdl -lib "work" "../base/cores/dqsinput_5x5.vhd" add_file -vhdl -lib "work" "../base/cores/fifo_cdt_200.vhd" add_file -vhdl -lib "work" "../base/code/adc_ad9219.vhd" - +add_file -vhdl -lib "work" "../base/code/adc_data_buffer.vhd" add_file -vhdl -lib "work" "trb3_periph_adc.vhd" diff --git a/ADC/trb3_periph_adc.vhd b/ADC/trb3_periph_adc.vhd index b27583a..225ff80 100644 --- a/ADC/trb3_periph_adc.vhd +++ b/ADC/trb3_periph_adc.vhd @@ -56,6 +56,7 @@ entity trb3_periph_adc is LMK_LE_2 : out std_logic; P_CLOCK : out std_logic; + POWER_ENABLE : out std_logic; FPGA_CS : out std_logic_vector(1 downto 0); FPGA_SCK : out std_logic_vector(1 downto 0); @@ -210,7 +211,12 @@ architecture trb3_periph_adc_arch of trb3_periph_adc is signal adc_restart_i : std_logic; signal adc_data : std_logic_vector(479 downto 0); - + signal adc_fco : std_logic_vector(119 downto 0); + signal adc_data_valid : std_logic_vector(11 downto 0); + + signal busadc_rx : CTRLBUS_RX; + signal busadc_tx : CTRLBUS_TX; + begin --------------------------------------------------------------------------- -- Reset Generation @@ -446,21 +452,39 @@ THE_ADC : entity work.adc_ad9219 ADC_DCO => ADC_DCO, DATA_OUT => adc_data, - FCO_OUT => open, - DATA_VALID_OUT => open, + FCO_OUT => adc_fco, + DATA_VALID_OUT => adc_data_valid, DEBUG => debug_adc ); -adc_restart_i <= '0'; + +THE_ADC_DATA_BUFFER : entity work.adc_data_buffer + generic map( + RESOLUTION => 10, + CHANNELS => 4, + DEVICES => 12 + ) + port map( + CLK => clk_100_i, + ADC_DATA_IN => adc_data, + ADC_FCO_IN => adc_fco, + ADC_DATA_VALID => adc_data_valid, + + ADC_RESET_OUT => adc_restart_i, + + BUS_RX => busadc_rx, + BUS_TX => busadc_tx + + ); --------------------------------------------------------------------------- -- Bus Handler --------------------------------------------------------------------------- THE_BUS_HANDLER : trb_net16_regio_bus_handler generic map( - PORT_NUMBER => 2, - PORT_ADDRESSES => (0 => x"d000", 1 => x"d400", others => x"0000"), - PORT_ADDR_MASK => (0 => 9, 1 => 5, others => 0) + PORT_NUMBER => 3, + PORT_ADDRESSES => (0 => x"d000", 1 => x"d400", 2 => x"e000", others => x"0000"), + PORT_ADDR_MASK => (0 => 9, 1 => 5, 2 => 8, others => 0) ) port map( CLK => clk_100_i, @@ -502,6 +526,17 @@ adc_restart_i <= '0'; BUS_NO_MORE_DATA_IN(1) => spifpga_busy, BUS_UNKNOWN_ADDR_IN(1) => '0', + BUS_READ_ENABLE_OUT(2) => busadc_rx.read, + BUS_WRITE_ENABLE_OUT(2) => busadc_rx.write, + BUS_DATA_OUT(2*32+31 downto 2*32) => busadc_rx.data, + BUS_ADDR_OUT(2*16+15 downto 2*16) => busadc_rx.addr, + BUS_TIMEOUT_OUT(2) => busadc_rx.timeout, + BUS_DATA_IN(2*32+31 downto 2*32) => busadc_tx.data, + BUS_DATAREADY_IN(2) => busadc_tx.ack, + BUS_WRITE_ACK_IN(2) => busadc_tx.ack, + BUS_NO_MORE_DATA_IN(2) => busadc_tx.nack, + BUS_UNKNOWN_ADDR_IN(2) => busadc_tx.unknown, + STAT_DEBUG => open ); @@ -593,6 +628,7 @@ THE_SPI_RELOAD : entity work.spi_flash_and_fpga_reload LMK_LE_1 <= spi_CS(4); -- active low LMK_LE_2 <= spi_CS(5); -- active low + POWER_ENABLE <= '1'; --------------------------------------------------------------------------- -- LED diff --git a/base/code/adc_ad9219.vhd b/base/code/adc_ad9219.vhd index 53ebfa0..fb535ca 100644 --- a/base/code/adc_ad9219.vhd +++ b/base/code/adc_ad9219.vhd @@ -46,6 +46,23 @@ signal clk_adcfast_i : std_logic_vector(1 downto 0); --200MHz signal clk_data : std_logic_vector(1 downto 0); --100MHz signal restart_i : std_logic_vector(1 downto 0); +type state_t is (S1,S2,S3,S4,S5); +type states_t is array(0 to 11) of state_t; +signal state : states_t; + +type value_it is array(0 to 4) of std_logic_vector(9 downto 0); +type value_t is array(0 to 11) of value_it; +signal value : value_t; +signal fifo_input : value_t; + +type fifo_t is array(0 to 11) of std_logic_vector(49 downto 0); +signal fifo_output: fifo_t; + +signal fifo_write : std_logic_vector(11 downto 0); +signal fifo_empty : std_logic_vector(11 downto 0); +signal fifo_last_empty : std_logic_vector(11 downto 0); + + begin THE_ADC_REF : entity work.pll_in200_out40 @@ -137,22 +154,99 @@ THE_RIGHT : entity work.dqsinput_5x5 gen_chips_left : for i in 0 to DEVICES_LEFT+DEVICES_RIGHT-1 generate - THE_FIFO : fifo_cdt_200 + + proc_collect_data : process begin + wait until rising_edge(clk_data(fpgaside(i))); + fifo_write(i) <= '0'; + case state(i) is + when S1 => + if q(i)(19 downto 16) = x"0011" then + state(i) <= S2; + value(i)(0)(9 downto 8) <= q(i)(1 downto 0 ); + value(i)(1)(9 downto 8) <= q(i)(5 downto 4 ); + value(i)(2)(9 downto 8) <= q(i)(9 downto 8 ); + value(i)(3)(9 downto 8) <= q(i)(13 downto 12); + value(i)(4)(9 downto 8) <= q(i)(17 downto 16); + + fifo_input(i) <= value(i); + fifo_input(i)(0)(1 downto 0) <= q(i)(3 downto 2 ); + fifo_input(i)(1)(1 downto 0) <= q(i)(7 downto 6 ); + fifo_input(i)(2)(1 downto 0) <= q(i)(11 downto 10); + fifo_input(i)(3)(1 downto 0) <= q(i)(15 downto 14); + fifo_input(i)(4)(1 downto 0) <= q(i)(19 downto 18); + fifo_write(i) <= '1'; + end if; + when S2 => + state(i) <= S3; + value(i)(0)(7 downto 4) <= q(i)(3 downto 0 ); + value(i)(1)(7 downto 4) <= q(i)(7 downto 4 ); + value(i)(2)(7 downto 4) <= q(i)(11 downto 8 ); + value(i)(3)(7 downto 4) <= q(i)(15 downto 12); + value(i)(4)(7 downto 4) <= q(i)(19 downto 16); + when S3 => + state(i) <= S4; + fifo_input(i) <= value(i); + fifo_input(i)(0)(3 downto 0) <= q(i)(3 downto 0 ); + fifo_input(i)(1)(3 downto 0) <= q(i)(7 downto 4 ); + fifo_input(i)(2)(3 downto 0) <= q(i)(11 downto 8 ); + fifo_input(i)(3)(3 downto 0) <= q(i)(15 downto 12); + fifo_input(i)(4)(3 downto 0) <= q(i)(19 downto 16); + fifo_write(i) <= '1'; + when S4 => + state(i) <= S5; + value(i)(0)(9 downto 6) <= q(i)(3 downto 0 ); + value(i)(1)(9 downto 6) <= q(i)(7 downto 4 ); + value(i)(2)(9 downto 6) <= q(i)(11 downto 8 ); + value(i)(3)(9 downto 6) <= q(i)(15 downto 12); + value(i)(4)(9 downto 6) <= q(i)(19 downto 16); + when S5 => + state(i) <= S1; + value(i)(0)(5 downto 2) <= q(i)(3 downto 0 ); + value(i)(1)(5 downto 2) <= q(i)(7 downto 4 ); + value(i)(2)(5 downto 2) <= q(i)(11 downto 8 ); + value(i)(3)(5 downto 2) <= q(i)(15 downto 12); + value(i)(4)(5 downto 2) <= q(i)(19 downto 16); + end case; + if restart_i(fpgaside(i)) = '1' then + state(i) <= S1; + end if; + end process; + + THE_FIFO : fifo_cdt_200 --60*16 port map( - Data(19 downto 0) => q(i), + Data(9 downto 0) => fifo_input(i)(0), + Data(19 downto 10) => fifo_input(i)(1), + Data(29 downto 20) => fifo_input(i)(2), + Data(39 downto 30) => fifo_input(i)(3), + Data(49 downto 40) => fifo_input(i)(4), WrClock => clk_data(fpgaside(i)), RdClock => CLK, - WrEn => '1', + WrEn => fifo_write(i), RdEn => '1', - Reset => '0', - RPReset => restart_i(fpgaside(i)), - Q(19 downto 0) => tmp(i), - Empty => open, + Reset => restart_i(fpgaside(i)), + RPReset => RESTART_IN, + Q(49 downto 0) => fifo_output(i), + Empty => fifo_empty(i), Full => open ); DEBUG(i) <= or_all(tmp(i)); + + proc_output : process begin + wait until rising_edge(CLK); + if fifo_last_empty(i) = '0' then + DATA_OUT(i*40+39 downto i*40+0) <= fifo_output(i)(39 downto 0); + FCO_OUT (i*10+9 downto i*10+0) <= fifo_output(i)(49 downto 40); + DATA_VALID_OUT(i) <= '1'; + else + DATA_VALID_OUT(i) <= '0'; + end if; + end process; + end generate; -end architecture; \ No newline at end of file +end architecture; + + + diff --git a/base/code/adc_data_buffer.vhd b/base/code/adc_data_buffer.vhd new file mode 100644 index 0000000..c3bc81d --- /dev/null +++ b/base/code/adc_data_buffer.vhd @@ -0,0 +1,117 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb3_components.all; + +entity adc_data_buffer is + generic( + CHANNELS : integer := 4; + DEVICES : integer := 12; + RESOLUTION : integer := 10 + ); + port( + CLK : in std_logic; + + ADC_DATA_IN : in std_logic_vector(DEVICES*CHANNELS*RESOLUTION-1 downto 0); + ADC_FCO_IN : in std_logic_vector(DEVICES*RESOLUTION-1 downto 0); + ADC_DATA_VALID : in std_logic_vector(DEVICES-1 downto 0); + + ADC_RESET_OUT : out std_logic; + + BUS_RX : in CTRLBUS_RX; + BUS_TX : out CTRLBUS_TX + ); +end entity; + + + +architecture adc_data_buffer_arch of adc_data_buffer is + +signal fifo_read : std_logic_vector(DEVICES*CHANNELS-1 downto 0); +signal fifo_empty : std_logic_vector(DEVICES*CHANNELS-1 downto 0); +signal fifo_full : std_logic_vector(DEVICES*CHANNELS-1 downto 0); +signal fifo_reset : std_logic; + +type dout_t is array(0 to DEVICES*CHANNELS-1) of std_logic_vector(17 downto 0); +signal fifo_dout : dout_t; + +type fifo_count_t is array(0 to DEVICES*CHANNELS-1) of std_logic_vector(10 downto 0); +signal fifo_count : fifo_count_t; + +signal ctrl_reg : std_logic_vector(31 downto 0); + +signal saved_addr : integer range 0 to DEVICES*CHANNELS-1; +signal fifo_wait_1, fifo_wait_2 : std_logic; + +begin + + +gen_data_fifo : for i in 0 to DEVICES*CHANNELS-1 generate + THE_FIFO : entity work.fifo_18x1k_oreg + port map ( + Data(9 downto 0) => ADC_DATA_IN(10*i+9 downto 10*i), + Data(17 downto 10) => ADC_FCO_IN (10*(i/CHANNELS)+7 downto 10*(i/CHANNELS)), + Clock => CLK, + WrEn => ADC_DATA_VALID(i / CHANNELS), + RdEn => fifo_read(i), + Reset => fifo_reset, + AmFullThresh => "1111110000", + Q => fifo_dout(i), + WCNT => fifo_count(i), + Empty => fifo_empty(i), + Full => open, + AlmostFull => fifo_full(i) + ); +end generate; + +fifo_wait_1 <= or_all(fifo_read) when rising_edge(CLK); +fifo_wait_2 <= fifo_wait_1 when rising_edge(CLK); + + +PROC_BUS : process begin + wait until rising_edge(CLK); + BUS_TX.ack <= '0'; + BUS_TX.nack <= '0'; + BUS_TX.unknown <= '0'; + ADC_RESET_OUT <= '0'; + fifo_read <= fifo_full; + + if BUS_RX.read = '1' then + if BUS_RX.addr(7 downto 0) = x"80" then + BUS_TX.data <= ctrl_reg; + BUS_TX.ack <= '1'; + elsif BUS_RX.addr(7 downto 0) < std_logic_vector(to_unsigned(DEVICES*CHANNELS,8)) then + saved_addr <= to_integer(unsigned(BUS_RX.addr(6 downto 0))); + fifo_read(to_integer(unsigned(BUS_RX.addr(6 downto 0)))) <= '1'; + else + BUS_TX.unknown <= '1'; + end if; + + elsif BUS_RX.write = '1' then + if BUS_RX.addr(7 downto 0) = x"80" then + ctrl_reg <= BUS_RX.data; + BUS_TX.ack <= '1'; + elsif BUS_RX.addr(7 downto 0) = x"81" then + ADC_RESET_OUT <= '1'; + BUS_TX.ack <= '1'; + else + BUS_TX.unknown <= '1'; + end if; + end if; + + if fifo_wait_2 = '1' then + BUS_TX.ack <= '1'; + BUS_TX.data(17 downto 0) <= fifo_dout(saved_addr); + BUS_TX.data(30 downto 18) <= (others => '0'); + BUS_TX.data(31) <= fifo_empty(saved_addr / CHANNELS); + end if; +end process; + + +end architecture; + + + diff --git a/base/trb3_periph_adc.lpf b/base/trb3_periph_adc.lpf index 11fe6b2..dc11dd1 100644 --- a/base/trb3_periph_adc.lpf +++ b/base/trb3_periph_adc.lpf @@ -182,7 +182,7 @@ DEFINE PORT GROUP "LMK_group" "LMK*" ; IOBUF GROUP "LMK_group" IO_TYPE=LVCMOS25 PULLMODE=DOWN DRIVE=8; LOCATE COMP "POWER_ENABLE" SITE "L1"; -IOBUF PORT "POWER_ENABLE" IO_TYPE=LVCMOS25 PULLMODE=UP DRIVE=8 ; +IOBUF PORT "POWER_ENABLE" IO_TYPE=LVCMOS25 PULLMODE=DOWN DRIVE=8 ; LOCATE COMP "P_CLOCK" SITE "K3"; IOBUF PORT "P_CLOCK" IO_TYPE=LVDS25 ; -- 2.43.0