]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
next step towards running ADC board
authorJan Michel <j.michel@gsi.de>
Tue, 22 Jul 2014 12:05:03 +0000 (14:05 +0200)
committerJan Michel <j.michel@gsi.de>
Tue, 22 Jul 2014 12:05:13 +0000 (14:05 +0200)
ADC/trb3_periph_adc.prj
ADC/trb3_periph_adc.vhd
base/code/adc_ad9219.vhd
base/code/adc_data_buffer.vhd [new file with mode: 0644]
base/trb3_periph_adc.lpf

index 620e91274948ad4f6ada7f4dbe74bbad045bfbb0..fd3b8df1b8a4fbe85012c3a70ec8d8f0e08e4d7d 100644 (file)
@@ -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"
 
index b27583a30780cc3fac97aff5058f74da8ba6ff4a..225ff80495a3607317329ff6a8bae45539a8f34f 100644 (file)
@@ -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
index 53ebfa0bfc9dd4e792094762db1a7f026c47440a..fb535cac5f287dea93581e1ee72e356fdf17848b 100644 (file)
@@ -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 (file)
index 0000000..c3bc81d
--- /dev/null
@@ -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;
+
+
+
index 11fe6b24897faed966cb86440be60c81d452f3b5..dc11dd1d27eecc50cd078eadc111b9340087ee2a 100644 (file)
@@ -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  ;