From bd0f9df7a3c3b8b8f7c21d832999d8e1a4ccc7e7 Mon Sep 17 00:00:00 2001 From: hadaq Date: Fri, 28 Sep 2012 13:17:02 +0000 Subject: [PATCH] added new files --- nxyter/source/adcmv3_components.vhd | 171 ++++++ nxyter/source/i2c_gstart.vhd | 238 ++++++++ nxyter/source/i2c_master.vhd | 212 +++++++ nxyter/source/i2c_sendb.vhd | 306 ++++++++++ nxyter/source/i2c_slim.vhd | 470 ++++++++++++++++ nxyter/source/nXyter.vhd | 46 -- nxyter/source/nxyter.vhd | 138 +++++ nxyter/source/nxyter_components.vhd | 58 ++ nxyter/source/slave_bus.vhd | 840 ++++++++++++++++++++++++++++ nxyter/source/slv_ped_thr_mem.vhd | 265 +++++++++ nxyter/source/slv_register.vhd | 205 +++++++ 11 files changed, 2903 insertions(+), 46 deletions(-) create mode 100644 nxyter/source/adcmv3_components.vhd create mode 100644 nxyter/source/i2c_gstart.vhd create mode 100644 nxyter/source/i2c_master.vhd create mode 100644 nxyter/source/i2c_sendb.vhd create mode 100644 nxyter/source/i2c_slim.vhd delete mode 100644 nxyter/source/nXyter.vhd create mode 100644 nxyter/source/nxyter.vhd create mode 100644 nxyter/source/nxyter_components.vhd create mode 100755 nxyter/source/slave_bus.vhd create mode 100644 nxyter/source/slv_ped_thr_mem.vhd create mode 100644 nxyter/source/slv_register.vhd diff --git a/nxyter/source/adcmv3_components.vhd b/nxyter/source/adcmv3_components.vhd new file mode 100644 index 0000000..4555731 --- /dev/null +++ b/nxyter/source/adcmv3_components.vhd @@ -0,0 +1,171 @@ +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.ALL; + +package adcmv3_components is + +------------------------------------------------------------------------------- +-- Components by Michael Boehmer +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- TRBNet interfaces +------------------------------------------------------------------------------- +component slave_bus + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + REGIO_ADDR_IN : in std_logic_vector(15 downto 0); + REGIO_DATA_IN : in std_logic_vector(31 downto 0); + REGIO_DATA_OUT : out std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN : in std_logic; + REGIO_WRITE_ENABLE_IN : in std_logic; + REGIO_TIMEOUT_IN : in std_logic; + REGIO_DATAREADY_OUT : out std_logic; + REGIO_WRITE_ACK_OUT : out std_logic; + REGIO_NO_MORE_DATA_OUT : out std_logic; + REGIO_UNKNOWN_ADDR_OUT : out std_logic; + SDA_IN : in std_logic; + SDA_OUT : out std_logic; + SCL_IN : in std_logic; + SCL_OUT : out std_logic; + SPI_CS_OUT : out std_logic; + SPI_SCK_OUT : out std_logic; + SPI_SDI_IN : in std_logic; + SPI_SDO_OUT : out std_logic); +end component slave_bus; + + +component slv_register + generic ( + RESET_VALUE : std_logic_vector(31 downto 0)); + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + BUSY_IN : in std_logic; + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + REG_DATA_IN : in std_logic_vector(31 downto 0); + REG_DATA_OUT : out std_logic_vector(31 downto 0); + STAT : out std_logic_vector(31 downto 0)); +end component slv_register; + + +component slv_ped_thr_mem + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + SLV_ADDR_IN : in std_logic_vector(10 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + BACKPLANE_IN : in std_logic_vector(2 downto 0); + MEM_CLK_IN : in std_logic; + MEM_ADDR_IN : in std_logic_vector(6 downto 0); + MEM_0_D_OUT : out std_logic_vector(17 downto 0); + MEM_1_D_OUT : out std_logic_vector(17 downto 0); + MEM_2_D_OUT : out std_logic_vector(17 downto 0); + MEM_3_D_OUT : out std_logic_vector(17 downto 0); + MEM_4_D_OUT : out std_logic_vector(17 downto 0); + MEM_5_D_OUT : out std_logic_vector(17 downto 0); + MEM_6_D_OUT : out std_logic_vector(17 downto 0); + MEM_7_D_OUT : out std_logic_vector(17 downto 0); + MEM_8_D_OUT : out std_logic_vector(17 downto 0); + MEM_9_D_OUT : out std_logic_vector(17 downto 0); + MEM_10_D_OUT : out std_logic_vector(17 downto 0); + MEM_11_D_OUT : out std_logic_vector(17 downto 0); + MEM_12_D_OUT : out std_logic_vector(17 downto 0); + MEM_13_D_OUT : out std_logic_vector(17 downto 0); + MEM_14_D_OUT : out std_logic_vector(17 downto 0); + MEM_15_D_OUT : out std_logic_vector(17 downto 0); + STAT : out std_logic_vector(31 downto 0)); +end component slv_ped_thr_mem; + +------------------------------------------------------------------------------- +-- I2C INterfaces +------------------------------------------------------------------------------- + +component i2c_master + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SDA_IN : in std_logic; + SDA_OUT : out std_logic; + SCL_IN : in std_logic; + SCL_OUT : out std_logic; + STAT : out std_logic_vector(31 downto 0)); +end component i2c_master; + + +component I2C_GSTART + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + START_IN : in std_logic; + DOSTART_IN : in std_logic; + I2C_SPEED_IN : in std_logic_vector(7 downto 0); + SDONE_OUT : out std_logic; + SOK_OUT : out std_logic; + SDA_IN : in std_logic; + SCL_IN : in std_logic; + R_SCL_OUT : out std_logic; + S_SCL_OUT : out std_logic; + R_SDA_OUT : out std_logic; + S_SDA_OUT : out std_logic; + BSM_OUT : out std_logic_vector(3 downto 0)); +end component I2C_GSTART; + + +component i2c_sendb + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + DOBYTE_IN : in std_logic; + I2C_SPEED_IN : in std_logic_vector(7 downto 0); + I2C_BYTE_IN : in std_logic_vector(8 downto 0); + I2C_BACK_OUT : out std_logic_vector(8 downto 0); + SDA_IN : in std_logic; + R_SDA_OUT : out std_logic; + S_SDA_OUT : out std_logic; + R_SCL_OUT : out std_logic; + S_SCL_OUT : out std_logic; + BDONE_OUT : out std_logic; + BOK_OUT : out std_logic; + BSM_OUT : out std_logic_vector(3 downto 0)); +end component i2c_sendb; + + +component i2c_slim + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + I2C_GO_IN : in std_logic; + ACTION_IN : in std_logic; + I2C_SPEED_IN : in std_logic_vector(5 downto 0); + I2C_ADR_IN : in std_logic_vector(7 downto 0); + I2C_CMD_IN : in std_logic_vector(7 downto 0); + I2C_DW_IN : in std_logic_vector(7 downto 0); + I2C_DR_OUT : out std_logic_vector(7 downto 0); + STATUS_OUT : out std_logic_vector(7 downto 0); + I2C_BUSY_OUT : out std_logic; + SDA_IN : in std_logic; + SDA_OUT : out std_logic; + SCL_IN : in std_logic; + SCL_OUT : out std_logic; + STAT : out std_logic_vector(31 downto 0)); +end component i2c_slim; + +end package; diff --git a/nxyter/source/i2c_gstart.vhd b/nxyter/source/i2c_gstart.vhd new file mode 100644 index 0000000..71aa45b --- /dev/null +++ b/nxyter/source/i2c_gstart.vhd @@ -0,0 +1,238 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv3_components.all; + +entity I2C_GSTART is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + START_IN : in std_logic; + DOSTART_IN : in std_logic; + I2C_SPEED_IN : in std_logic_vector(7 downto 0); + SDONE_OUT : out std_logic; + SOK_OUT : out std_logic; + SDA_IN : in std_logic; + SCL_IN : in std_logic; + R_SCL_OUT : out std_logic; + S_SCL_OUT : out std_logic; + R_SDA_OUT : out std_logic; + S_SDA_OUT : out std_logic; + BSM_OUT : out std_logic_vector(3 downto 0) + ); +end entity; + +architecture Behavioral of I2C_GSTART is + +-- Signals + type STATES is (SLEEP, + P_SCL, + WCTR0, + P_SDA, + WCTR1, + P_CHK, + S_CHK0, + RS_SDA, + S_CHK1, + ERROR, + DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + signal bsm : std_logic_vector(3 downto 0); + signal cctr : std_logic_vector(7 downto 0); -- counter for bit length + + signal cycdone_x : std_logic; + signal cycdone : std_logic; -- one counter period done + + signal load_cyc_x : std_logic; + signal load_cyc : std_logic; + signal dec_cyc_x : std_logic; + signal dec_cyc : std_logic; + signal sdone_x : std_logic; + signal sdone : std_logic; -- Start/Stop done + signal sok_x : std_logic; + signal sok : std_logic; -- Start/Stop OK + + signal r_scl : std_logic; + signal s_scl : std_logic; + signal r_sda : std_logic; + signal s_sda : std_logic; + +-- Moduls + +begin + +-- Countdown for one half of SCL (adjustable clock width) + THE_CYC_CTR_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + cctr <= (others => '0'); + elsif( load_cyc = '1' ) then + cctr <= i2c_speed_in; + elsif( dec_cyc = '1' ) then + cctr <= cctr - 1; + end if; + end if; + end process THE_CYC_CTR_PROC; + +-- end of cycle recognition + cycdone_x <= '1' when (cctr = x"00") else '0'; + +-- The main state machine +-- State memory process + STATE_MEM: process( clk_in ) + begin + if ( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + load_cyc <= '0'; + dec_cyc <= '0'; + sdone <= '0'; + sok <= '0'; + cycdone <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + load_cyc <= load_cyc_x; + dec_cyc <= dec_cyc_x; + sdone <= sdone_x; + sok <= sok_x; + cycdone <= cycdone_x; + end if; + end if; + end process STATE_MEM; + +-- Transition matrix + TRANSFORM: process(CURRENT_STATE, dostart_in, start_in, sda_in, scl_in, cycdone) + begin + NEXT_STATE <= SLEEP; + load_cyc_x <= '0'; + dec_cyc_x <= '0'; + sdone_x <= '0'; + sok_x <= '1'; + case CURRENT_STATE is + when SLEEP => if ( (dostart_in = '1') and (start_in = '1') ) then + NEXT_STATE <= S_CHK0; -- generate a start condition + load_cyc_x <= '1'; + elsif( (dostart_in = '1') and (start_in = '0') ) then + NEXT_STATE <= P_SCL; -- generate a stop condition + load_cyc_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when P_SCL => NEXT_STATE <= WCTR0; + dec_cyc_x <= '1'; + when S_CHK0 => if( (sda_in = '1') and (scl_in = '1') ) then + NEXT_STATE <= RS_SDA; + else + NEXT_STATE <= ERROR; + sok_x <= '0'; + end if; + when RS_SDA => NEXT_STATE <= WCTR0; + dec_cyc_x <= '1'; + when WCTR0 => if ( (cycdone = '1') and (start_in = '1') ) then + NEXT_STATE <= S_CHK1; + elsif( (cycdone = '1') and (start_in = '0') ) then + NEXT_STATE <= P_SDA; + load_cyc_x <= '1'; + else + NEXT_STATE <= WCTR0; + dec_cyc_x <= '1'; + end if; + when S_CHK1 => if( (sda_in = '0') and (scl_in = '1') ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= ERROR; + sok_x <= '0'; + end if; + when P_SDA => NEXT_STATE <= WCTR1; + dec_cyc_x <= '1'; + when WCTR1 => if( (cycdone = '1') ) then + NEXT_STATE <= P_CHK; + else + NEXT_STATE <= WCTR1; + dec_cyc_x <= '1'; + end if; + when P_CHK => if( (sda_in = '1') and (scl_in = '1') ) then + NEXT_STATE <= DONE; + sdone_x <= '1'; + else + NEXT_STATE <= ERROR; + sok_x <= '0'; + end if; + when ERROR => if( dostart_in = '0' ) then + NEXT_STATE <= SLEEP; + else + NEXT_STATE <= ERROR; + sdone_x <= '1'; + sok_x <= '0'; + end if; + when DONE => if( dostart_in = '0' ) then + NEXT_STATE <= SLEEP; + else + NEXT_STATE <= DONE; + sdone_x <= '1'; + end if; + when others => NEXT_STATE <= SLEEP; + end case; + end process TRANSFORM; + +-- Output decoding + DECODE: process(CURRENT_STATE) + begin + case CURRENT_STATE is + when SLEEP => bsm <= x"0"; + when S_CHK0 => bsm <= x"1"; + when RS_SDA => bsm <= x"2"; + when P_SCL => bsm <= x"3"; + when WCTR0 => bsm <= x"4"; + when S_CHK1 => bsm <= x"5"; + when P_SDA => bsm <= x"6"; + when WCTR1 => bsm <= x"7"; + when P_CHK => bsm <= x"8"; + when DONE => bsm <= x"9"; + when ERROR => bsm <= x"e"; + when others => bsm <= x"f"; + end case; + end process DECODE; + + S_R_GEN: process(CURRENT_STATE) + begin + if ( CURRENT_STATE = P_SCL ) then + r_scl <= '0'; + s_scl <= '1'; + r_sda <= '0'; + s_sda <= '0'; + elsif( CURRENT_STATE = RS_SDA ) then + r_scl <= '0'; + s_scl <= '0'; + r_sda <= '1'; + s_sda <= '0'; + elsif( CURRENT_STATE = P_SDA ) then + r_scl <= '0'; + s_scl <= '0'; + r_sda <= '0'; + s_sda <= '1'; + else + r_scl <= '0'; + s_scl <= '0'; + r_sda <= '0'; + s_sda <= '0'; + end if; + end process S_R_GEN; + +-- Outputs + r_scl_out <= r_scl; + s_scl_out <= s_scl; + r_sda_out <= r_sda; + s_sda_out <= s_sda; + sdone_out <= sdone; + sok_out <= sok; + +-- Debug + bsm_out <= bsm; + +end Behavioral; diff --git a/nxyter/source/i2c_master.vhd b/nxyter/source/i2c_master.vhd new file mode 100644 index 0000000..d615674 --- /dev/null +++ b/nxyter/source/i2c_master.vhd @@ -0,0 +1,212 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv3_components.all; + +entity i2c_master is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + + -- I2C connections + SDA_IN : in std_logic; + SDA_OUT : out std_logic; + SCL_IN : in std_logic; + SCL_OUT : out std_logic; + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of i2c_master is + +-- Signals + type STATES is (SLEEP, + RD_BSY, + WR_BSY, + RD_RDY, + WR_RDY, + RD_ACK, + WR_ACK, + DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + +-- slave bus signals + signal slv_busy_x : std_logic; + signal slv_busy : std_logic; + signal slv_ack_x : std_logic; + signal slv_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + + signal reg_slv_data_in : std_logic_vector(31 downto 0); -- registered data input + signal reg_slv_data_out : std_logic_vector(31 downto 0); -- read back data + signal reg_busy : std_logic; + + signal status_data : std_logic_vector(31 downto 0); + signal i2c_debug : std_logic_vector(31 downto 0); + +begin + +--------------------------------------------------------- +-- I2C master -- +--------------------------------------------------------- + + THE_I2C_SLIM: i2c_slim + port map( + CLK_IN => clk_in, + RESET_IN => reset_in, + -- I2C command / setup + I2C_GO_IN => reg_slv_data_in(31), + ACTION_IN => reg_slv_data_in(30), + I2C_SPEED_IN => reg_slv_data_in(29 downto 24), + I2C_ADR_IN => reg_slv_data_in(23 downto 16), + I2C_CMD_IN => reg_slv_data_in(15 downto 8), + I2C_DW_IN => reg_slv_data_in(7 downto 0), + I2C_DR_OUT => status_data(7 downto 0), + STATUS_OUT => status_data(31 downto 24), + I2C_BUSY_OUT => reg_busy, + -- I2C connections + SDA_IN => sda_in, + SDA_OUT => sda_out, + SCL_IN => scl_in, + SCL_OUT => scl_out, + -- Debug + STAT => i2c_debug + ); + + status_data(23 downto 21) <= (others => '0'); + status_data(20 downto 16) <= i2c_debug(4 downto 0); + status_data(15 downto 8) <= (others => '0'); + +-- Fake + stat <= i2c_debug; + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process + STATE_MEM: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_busy <= '0'; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_busy <= slv_busy_x; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; + end process STATE_MEM; + +-- Transition matrix + TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, reg_busy ) + begin + NEXT_STATE <= SLEEP; + slv_busy_x <= '0'; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => if ( (reg_busy = '0') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (reg_busy = '0') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + elsif( (reg_busy = '1') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + elsif( (reg_busy = '1') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + when WR_RDY => NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + when RD_ACK => if ( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + when WR_ACK => if ( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + when RD_BSY => if ( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + end if; + when WR_BSY => if ( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + end if; + when DONE => NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; + end case; + end process TRANSFORM; + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- + +-- register write + THE_WRITE_REG_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_in <= (others => '0'); + elsif( store_wr = '1' ) then + reg_slv_data_in <= slv_data_in; + end if; + end if; + end process THE_WRITE_REG_PROC; + +-- register read + THE_READ_REG_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_out <= (others => '0'); + elsif( store_rd = '1' ) then + reg_slv_data_out <= status_data; + end if; + end if; + end process THE_READ_REG_PROC; + +-- output signals + slv_ack_out <= slv_ack; + slv_busy_out <= slv_busy; + slv_data_out <= reg_slv_data_out; + +end Behavioral; diff --git a/nxyter/source/i2c_sendb.vhd b/nxyter/source/i2c_sendb.vhd new file mode 100644 index 0000000..778878a --- /dev/null +++ b/nxyter/source/i2c_sendb.vhd @@ -0,0 +1,306 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv3_components.all; + +entity i2c_sendb is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + DOBYTE_IN : in std_logic; + I2C_SPEED_IN : in std_logic_vector( 7 downto 0 ); + I2C_BYTE_IN : in std_logic_vector( 8 downto 0 ); + I2C_BACK_OUT : out std_logic_vector( 8 downto 0 ); + SDA_IN : in std_logic; + R_SDA_OUT : out std_logic; + S_SDA_OUT : out std_logic; +-- SCL_IN : in std_logic; + R_SCL_OUT : out std_logic; + S_SCL_OUT : out std_logic; + BDONE_OUT : out std_logic; + BOK_OUT : out std_logic; + BSM_OUT : out std_logic_vector( 3 downto 0 ) + ); +end entity; + +architecture Behavioral of i2c_sendb is + +-- Signals + type STATES is (SLEEP, + LCL, + WCL, + LCH, + WCH, + FREE, + DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + signal bsm : std_logic_vector( 3 downto 0 ); + + signal inc_bit_x : std_logic; + signal inc_bit : std_logic; -- increment bit counter for byte to send + signal rst_bit_x : std_logic; + signal rst_bit : std_logic; -- reset bit counter for byte to send + signal load_cyc_x : std_logic; + signal load_cyc : std_logic; -- load cycle counter (SCL length) + signal dec_cyc_x : std_logic; + signal dec_cyc : std_logic; -- decrement cycle counter (SCL length) + signal load_sr_x : std_logic; + signal load_sr : std_logic; -- load output shift register + signal shift_o_x : std_logic; + signal shift_o : std_logic; -- output shift register control + signal shift_i_x : std_logic; + signal shift_i : std_logic; -- input shift register control + signal bdone_x : std_logic; + signal bdone : std_logic; + signal r_scl_x : std_logic; + signal r_scl : std_logic; -- output for SCL + signal s_scl_x : std_logic; + signal s_scl : std_logic; -- output for SCL + + signal bctr : std_logic_vector( 3 downto 0 ); -- bit counter (1...9) + signal cctr : std_logic_vector( 7 downto 0 ); -- counter for bit length + signal bok : std_logic; + signal cycdone : std_logic; -- one counter period done + signal bytedone : std_logic; -- all bits sents + signal in_sr : std_logic_vector( 8 downto 0 ); -- shift register for byte in + signal out_sr : std_logic_vector( 8 downto 0 ); -- shift register for byte out + signal i2c_back : std_logic_vector( 8 downto 0 ); -- shift register for byte in + signal r_sda : std_logic; -- output for SDA + signal s_sda : std_logic; -- output for SDA + signal load : std_logic; -- delay register + signal i2c_d : std_logic; -- auxiliary register + +-- Moduls + +begin + +-- Bit counter (for byte to send) + THE_BIT_CTR_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + bctr <= (others => '0'); + elsif( rst_bit = '1' ) then + bctr <= (others => '0'); + elsif( inc_bit = '1' ) then + bctr <= bctr + 1; + end if; + end if; + end process THE_BIT_CTR_PROC; + +-- end of byte recognition + bytedone <= '1' when (bctr = x"9") else '0'; + +-- Countdown for one half of SCL (adjustable clock width) + THE_CYC_CTR_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + cctr <= (others => '0'); + elsif( load_cyc = '1' ) then + cctr <= i2c_speed_in; + elsif( dec_cyc = '1' ) then + cctr <= cctr - 1; + end if; + end if; + end process THE_CYC_CTR_PROC; + +-- end of cycle recognition + cycdone <= '1' when (cctr = x"00") else '0'; + +-- Bit output + THE_BIT_OUT_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + out_sr <= (others => '0'); + i2c_d <= '1'; + elsif( load_sr = '1' ) then + out_sr <= i2c_byte_in; + i2c_d <= '1'; + elsif( shift_o = '1' ) then + i2c_d <= out_sr(8); + out_sr(8 downto 0) <= out_sr(7 downto 0) & '0'; + end if; + end if; + end process THE_BIT_OUT_PROC; + +-- Bit input + THE_BIT_IN_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + in_sr <= (others => '1'); + elsif( shift_o = '1' ) then + in_sr(8 downto 1) <= in_sr(7 downto 0); + in_sr(0) <= sda_in; + end if; + end if; + end process THE_BIT_IN_PROC; + +-- Output register for readback data (could be reduced to SR_IN_INT) + THE_I2C_BACK_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + i2c_back <= (others => '1'); + elsif( shift_i = '1' ) then + i2c_back(8 downto 1) <= in_sr(7 downto 0); + i2c_back(0) <= sda_in; + end if; + end if; + end process THE_I2C_BACK_PROC; + +-- ByteOK is the inverted ACK bit from readback data. + bok <= not i2c_back(0); -- BUG + +-- The main state machine +-- State memory process + STATE_MEM: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1') then + CURRENT_STATE <= SLEEP; + inc_bit <= '0'; + rst_bit <= '0'; + load_cyc <= '0'; + dec_cyc <= '0'; + load_sr <= '0'; + shift_o <= '0'; + shift_i <= '0'; + bdone <= '0'; + r_scl <= '0'; + s_scl <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + inc_bit <= inc_bit_x; + rst_bit <= rst_bit_x; + load_cyc <= load_cyc_x; + dec_cyc <= dec_cyc_x; + load_sr <= load_sr_x; + shift_o <= shift_o_x; + shift_i <= shift_i_x; + bdone <= bdone_x; + r_scl <= r_scl_x; + s_scl <= s_scl_x; + end if; + end if; + end process STATE_MEM; + +-- Transition matrix + TRANSFORM: process(CURRENT_STATE, dobyte_in, cycdone, bytedone) + begin + NEXT_STATE <= SLEEP; + inc_bit_x <= '0'; + rst_bit_x <= '0'; + load_cyc_x <= '0'; + dec_cyc_x <= '0'; + load_sr_x <= '0'; + shift_o_x <= '0'; + shift_i_x <= '0'; + bdone_x <= '0'; + r_scl_x <= '0'; + s_scl_x <= '0'; + case CURRENT_STATE is + when SLEEP => if( dobyte_in = '1' ) then + NEXT_STATE <= LCL; + inc_bit_x <= '1'; + load_cyc_x <= '1'; + shift_o_x <= '1'; + r_scl_x <= '1'; + else + NEXT_STATE <= SLEEP; + load_sr_x <= '1'; + end if; + when LCL => NEXT_STATE <= WCL; + dec_cyc_x <= '1'; + when WCL => if( cycdone = '1' ) then + NEXT_STATE <= LCH; + load_cyc_x <= '1'; + s_scl_x <= '1'; + else + NEXT_STATE <= WCL; + dec_cyc_x <= '1'; + end if; + when LCH => NEXT_STATE <= WCH; + dec_cyc_x <= '1'; + when WCH => if ( (cycdone = '1') and (bytedone = '0') ) then + NEXT_STATE <= LCL; + inc_bit_x <= '1'; + load_cyc_x <= '1'; + shift_o_x <= '1'; + r_scl_x <= '1'; + elsif( (cycdone = '1') and (bytedone = '1') ) then + NEXT_STATE <= FREE; + shift_o_x <= '1'; + shift_i_x <= '1'; + r_scl_x <= '1'; + else + NEXT_STATE <= WCH; + dec_cyc_x <= '1'; + end if; + when FREE => NEXT_STATE <= DONE; + rst_bit_x <= '1'; + bdone_x <= '1'; + when DONE => if( dobyte_in = '0' ) then + NEXT_STATE <= SLEEP; + else + NEXT_STATE <= DONE; + rst_bit_x <= '1'; + bdone_x <= '1'; + end if; + -- Just in case... + when others => NEXT_STATE <= SLEEP; + end case; + end process TRANSFORM; + +-- Output decoding + DECODE: process(CURRENT_STATE) + begin + case CURRENT_STATE is + when SLEEP => bsm <= x"0"; + when LCL => bsm <= x"1"; + when WCL => bsm <= x"2"; + when LCH => bsm <= x"3"; + when WCH => bsm <= x"4"; + when FREE => bsm <= x"5"; + when DONE => bsm <= x"6"; + when others => bsm <= x"f"; + end case; + end process DECODE; + +-- SCL and SDA output pulses + THE_SDA_OUT_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + load <= '0'; -- was a bug, found 081008 + r_sda <= '0'; + s_sda <= '0'; + else + load <= shift_o; + r_sda <= load and not i2c_d; + s_sda <= load and i2c_d; + end if; + end if; + end process THE_SDA_OUT_PROC; + +-- Outputs + r_scl_out <= r_scl; + s_scl_out <= s_scl; + r_sda_out <= r_sda; + s_sda_out <= s_sda; + + i2c_back_out <= i2c_back; + + bdone_out <= bdone; + bok_out <= bok; + +-- Debugging + bsm_out <= bsm; + +end Behavioral; diff --git a/nxyter/source/i2c_slim.vhd b/nxyter/source/i2c_slim.vhd new file mode 100644 index 0000000..656f9c9 --- /dev/null +++ b/nxyter/source/i2c_slim.vhd @@ -0,0 +1,470 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv3_components.all; + +-- BUG: does alway set bit 0 of address byte to zero !!!! +-- REMARK: this is not a bug, but a feature.... + +entity i2c_slim is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- I2C command / setup + I2C_GO_IN : in std_logic; -- startbit to trigger I2C actions + ACTION_IN : in std_logic; -- '0' -> write, '1' -> read + I2C_SPEED_IN : in std_logic_vector( 5 downto 0 ); -- speed adjustment (to be defined) + I2C_ADR_IN : in std_logic_vector( 7 downto 0 ); -- I2C address byte (R/W bit is ignored) + I2C_CMD_IN : in std_logic_vector( 7 downto 0 ); -- I2C command byte (sent after address byte) + I2C_DW_IN : in std_logic_vector( 7 downto 0 ); -- data word for write command + I2C_DR_OUT : out std_logic_vector( 7 downto 0 ); -- data word from read command + STATUS_OUT : out std_logic_vector( 7 downto 0 ); -- status and error bits + I2C_BUSY_OUT : out std_logic; + + -- I2C connections + SDA_IN : in std_logic; + SDA_OUT : out std_logic; + SCL_IN : in std_logic; + SCL_OUT : out std_logic; + + -- Debug + STAT : out std_logic_vector(31 downto 0) + ); +end i2c_slim; + +architecture Behavioral of i2c_slim is + +-- Signals + type STATES is (SLEEP, + LOADA, + GSTART, + SENDA, + LOADC, + SENDC, + LOADD, + SENDD, + GSTOP, + INC, + E_START, + E_ADDR, + E_CMD, + E_WD, + E_RSTART, + E_RADDR, + DONE, + FAILED, + CLRERR); + signal CURRENT_STATE, NEXT_STATE: STATES; + + signal bsm : std_logic_vector( 4 downto 0 ); + signal phase : std_logic; -- '0' => first phase, '1' => second phase of read cycle + + signal start_x : std_logic; + signal start : std_logic; -- '0' => generate STOP, '1' => generate START + signal dostart_x : std_logic; + signal dostart : std_logic; -- trigger the GenStart module + signal dobyte_x : std_logic; + signal dobyte : std_logic; -- trigger the ByteSend module + signal i2c_done_x : std_logic; + signal i2c_done : std_logic; -- acknowledge signal to the outside world + signal running_x : std_logic; + signal running : std_logic; -- legacy + + signal load_a_x : std_logic; + signal load_a : std_logic; + signal load_c_x : std_logic; + signal load_c : std_logic; + signal load_d_x : std_logic; + signal load_d : std_logic; + + signal sdone : std_logic; -- acknowledge signal from GenStart module + signal sok : std_logic; -- status signal from GenStart module + signal bdone : std_logic; -- acknowledge signal from SendByte module + signal bok : std_logic; -- status signal from SendByte module + signal e_sf : std_logic; -- Start failed + signal e_anak : std_logic; -- Adress byte NAK + signal e_cnak : std_logic; -- Command byte NAK + signal e_dnak : std_logic; -- Data byte NAK + signal e_rsf : std_logic; -- Repeated Start failed + signal e_ranak : std_logic; -- Repeated Adress NAK + signal i2c_byte : std_logic_vector( 8 downto 0 ); + signal i2c_dr : std_logic_vector( 8 downto 0 ); + + signal s_scl : std_logic; + signal r_scl : std_logic; + signal s_sda : std_logic; + signal r_sda : std_logic; + signal r_scl_gs : std_logic; + signal s_scl_gs : std_logic; + signal r_sda_gs : std_logic; + signal s_sda_gs : std_logic; + signal r_scl_sb : std_logic; + signal s_scl_sb : std_logic; + signal r_sda_sb : std_logic; + signal s_sda_sb : std_logic; + + signal gs_debug : std_logic_vector(3 downto 0); + + signal i2c_speed : std_logic_vector(7 downto 0); + +begin + + i2c_speed <= i2c_speed_in & "00"; + +-- Read phase indicator + THE_PHASE_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + phase <= '0'; + elsif( CURRENT_STATE = INC ) then + phase <= '1'; + elsif( (CURRENT_STATE = DONE) or (CURRENT_STATE = SLEEP) ) then + phase <= '0'; + end if; + end if; + end process THE_PHASE_PROC; + +-- The main state machine +-- State memory process + STATE_MEM: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + start <= '0'; + dostart <= '0'; + dobyte <= '0'; + i2c_done <= '0'; + running <= '0'; + load_a <= '0'; + load_c <= '0'; + load_d <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + start <= start_x; + dostart <= dostart_x; + dobyte <= dobyte_x; + i2c_done <= i2c_done_x; + running <= running_x; + load_a <= load_a_x; + load_c <= load_c_x; + load_d <= load_d_x; + end if; + end if; + end process STATE_MEM; + +-- Transition matrix + TRANSFORM: process(CURRENT_STATE, i2c_go_in, sdone, sok, phase, bdone, bok, action_in) + begin + NEXT_STATE <= SLEEP; + start_x <= '0'; + dostart_x <= '0'; + dobyte_x <= '0'; + i2c_done_x <= '0'; + running_x <= '1'; + load_a_x <= '0'; + load_c_x <= '0'; + load_d_x <= '0'; + case CURRENT_STATE is + when SLEEP => if( i2c_go_in = '1' ) then + NEXT_STATE <= CLRERR; + else + NEXT_STATE <= SLEEP; + running_x <= '0'; + end if; + when CLRERR => NEXT_STATE <= LOADA; + load_a_x <= '1'; + when LOADA => NEXT_STATE <= GSTART; + start_x <= '1'; + dostart_x <= '1'; + when GSTART => if ( (sdone = '1') and (sok = '1') ) then + NEXT_STATE <= SENDA; + dobyte_x <= '1'; + elsif( (sdone = '1') and (sok = '0') and (phase = '0') ) then + NEXT_STATE <= E_START; -- first START condition failed + elsif( (sdone = '1') and (sok = '0') and (phase = '1') ) then + NEXT_STATE <= E_RSTART; -- second START condition failed + else + NEXT_STATE <= GSTART; + start_x <= '1'; + dostart_x <= '1'; + end if; + when E_START => NEXT_STATE <= FAILED; + dostart_x <= '1'; + when E_RSTART => NEXT_STATE <= FAILED; + dostart_x <= '1'; + when SENDA => if ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then + NEXT_STATE <= LOADC; -- I2C write + load_c_x <= '1'; + elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '0') ) then + NEXT_STATE <= LOADC; -- I2C read, send register address + load_c_x <= '1'; + elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '1') ) then + NEXT_STATE <= LOADD; -- I2C read, send 0xff dummy byte + load_d_x <= '1'; + elsif( (bdone = '1') and (bok = '0') and (phase = '0') ) then + NEXT_STATE <= E_ADDR; -- first address phase failed + elsif( (bdone = '1') and (bok = '0') and (phase = '1') ) then + NEXT_STATE <= E_RADDR; -- second address phase failed + else + NEXT_STATE <= SENDA; + dobyte_x <= '1'; + end if; + when E_ADDR => NEXT_STATE <= FAILED; + dostart_x <= '1'; + when E_RADDR => NEXT_STATE <= FAILED; + dostart_x <= '1'; + when LOADC => NEXT_STATE <= SENDC; +-- dobyte_x <= '1'; + when SENDC => if ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then + NEXT_STATE <= LOADD; -- I2C write, prepare data + load_d_x <= '1'; + elsif( (bdone = '1') and (bok = '1') and (action_in = '1') ) then + NEXT_STATE <= GSTOP; -- I2C read, first phase ends + dostart_x <= '1'; + elsif( (bdone = '1') and (bok = '0') ) then + NEXT_STATE <= E_CMD; -- command phase failed + else + NEXT_STATE <= SENDC; + dobyte_x <= '1'; + end if; + when E_CMD => NEXT_STATE <= FAILED; + dostart_x <= '1'; + when LOADD => NEXT_STATE <= SENDD; + when SENDD => if ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then + NEXT_STATE <= GSTOP; -- I2C write, data phase failed + dostart_x <= '1'; + elsif( (bdone = '1') and (action_in = '1') ) then + NEXT_STATE <= GSTOP; -- I2C read, data phase + dostart_x <= '1'; + elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then + NEXT_STATE <= E_WD; -- I2C write, data phase failed + else + NEXT_STATE <= SENDD; + dobyte_x <= '1'; + end if; + when E_WD => NEXT_STATE <= FAILED; + dostart_x <= '1'; + when GSTOP => if ( (sdone = '1') and (action_in = '0') ) then + NEXT_STATE <= DONE; + elsif( (sdone = '1') and (action_in = '1') and (phase = '1') ) then + NEXT_STATE <= DONE; + elsif( (sdone = '1') and (action_in = '1') and (phase = '0') ) then + NEXT_STATE <= INC; + else + NEXT_STATE <= GSTOP; + dostart_x <= '1'; + end if; + when INC => NEXT_STATE <= LOADA; + load_a_x <= '1'; + when FAILED => if( sdone = '1' ) then + NEXT_STATE <= DONE; + i2c_done_x <= '1'; + running_x <= '0'; + else + NEXT_STATE <= FAILED; + dostart_x <= '1'; + end if; + when DONE => if( i2c_go_in = '1' ) then + NEXT_STATE <= DONE; + i2c_done_x <= '1'; + running_x <= '0'; + else + NEXT_STATE <= SLEEP; + end if; + -- Just in case... + when others => NEXT_STATE <= SLEEP; + end case; + end process TRANSFORM; + +-- Output decoding + DECODE: process(CURRENT_STATE) + begin + case CURRENT_STATE is + when SLEEP => bsm <= b"00000"; -- 00 + when CLRERR => bsm <= b"01100"; -- 0c + when LOADA => bsm <= b"00001"; -- 01 + when GSTART => bsm <= b"00010"; -- 02 + when SENDA => bsm <= b"00011"; -- 03 + when LOADC => bsm <= b"00100"; -- 04 + when SENDC => bsm <= b"00101"; -- 05 + when LOADD => bsm <= b"00110"; -- 06 + when SENDD => bsm <= b"00111"; -- 07 + when GSTOP => bsm <= b"01000"; -- 08 + when INC => bsm <= b"01001"; -- 09 + when FAILED => bsm <= b"01010"; -- 0a + when DONE => bsm <= b"01011"; -- 0b + when E_START => bsm <= b"10000"; -- 10 + when E_RSTART => bsm <= b"10001"; -- 11 + when E_ADDR => bsm <= b"10010"; -- 12 + when E_RADDR => bsm <= b"10011"; -- 13 + when E_CMD => bsm <= b"10100"; -- 14 + when E_WD => bsm <= b"10101"; -- 15 + when others => bsm <= b"11111"; -- 1f + end case; + end process DECODE; + +-- We need to load different data sets +--LOAD_DATA_PROC: process( clk_in, reset_in, CURRENT_STATE, action_in, phase) + LOAD_DATA_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + i2c_byte <= (others => '1'); + elsif( (CURRENT_STATE = LOADA) and (phase = '0') ) then + i2c_byte <= i2c_adr_in(6 downto 0) & '0' & '1'; -- send write address, receive ACK + elsif( (CURRENT_STATE = LOADA) and (phase = '1') ) then + i2c_byte <= i2c_adr_in(6 downto 0) & '1' & '1'; -- send read address, receive ACK + elsif( (CURRENT_STATE = LOADC) and (action_in = '0') ) then + i2c_byte <= i2c_cmd_in(7 downto 1) & '0' & '1'; -- send command byte (WRITE), receive ACK + elsif( (CURRENT_STATE = LOADC) and (action_in = '1') ) then + i2c_byte <= i2c_cmd_in(7 downto 1) & '1' & '1'; -- send command byte (READ), receive ACK + elsif( (CURRENT_STATE = LOADD) and (action_in = '0') ) then + i2c_byte <= i2c_dw_in & '1'; -- send data byte, receive ACK + elsif( (CURRENT_STATE = LOADD) and (action_in = '1') ) then + i2c_byte <= x"ff" & '1'; -- send 0xff byte, send NACK + end if; + end if; + end process LOAD_DATA_PROC; + +-- The SendByte module + THE_I2C_SENDB: I2C_SENDB + port map( + CLK_IN => clk_in, + RESET_IN => reset_in, + DOBYTE_IN => dobyte, + I2C_SPEED_IN => i2c_speed, + I2C_BYTE_IN => i2c_byte, + I2C_BACK_OUT => i2c_dr, + SDA_IN => sda_in, + R_SDA_OUT => r_sda_sb, + S_SDA_OUT => s_sda_sb, +-- SCL_IN => scl_in, + R_SCL_OUT => r_scl_sb, + S_SCL_OUT => s_scl_sb, + BDONE_OUT => bdone, + BOK_OUT => bok, + BSM_OUT => open + ); + +-- The GenStart module + THE_I2C_GSTART: I2C_GSTART + port map( + CLK_IN => clk_in, + RESET_IN => reset_in, + START_IN => start, + DOSTART_IN => dostart, + I2C_SPEED_IN => i2c_speed, + SDONE_OUT => sdone, + SOK_OUT => sok, + SDA_IN => sda_in, + SCL_IN => scl_in, + R_SCL_OUT => r_scl_gs, + S_SCL_OUT => s_scl_gs, + R_SDA_OUT => r_sda_gs, + S_SDA_OUT => s_sda_gs, + BSM_OUT => gs_debug --open + ); + + r_scl <= r_scl_gs or r_scl_sb; + s_scl <= s_scl_gs or s_scl_sb; + r_sda <= r_sda_gs or r_sda_sb; + s_sda <= s_sda_gs or s_sda_sb; + +-- Output flipflops for SCL and SDA lines + THE_SCL_SDA_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + scl_out <= '1'; + sda_out <= '1'; + elsif( (r_scl = '1') and (s_scl = '0') ) then + scl_out <= '0'; + elsif( (r_scl = '0') and (s_scl = '1') ) then + scl_out <= '1'; + elsif( (r_sda = '1') and (s_sda = '0') ) then + sda_out <= '0'; + elsif( (r_sda = '0') and (s_sda = '1') ) then + sda_out <= '1'; + end if; + end if; + end process THE_SCL_SDA_PROC; + +-- Error bits + THE_ERR_REG_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + e_sf <= '0'; + e_anak <= '0'; + e_cnak <= '0'; + e_dnak <= '0'; + e_rsf <= '0'; + e_ranak <= '0'; + elsif( CURRENT_STATE = CLRERR ) then + e_sf <= '0'; + e_anak <= '0'; + e_cnak <= '0'; + e_dnak <= '0'; + e_rsf <= '0'; + e_ranak <= '0'; + elsif( CURRENT_STATE = E_START ) then + e_sf <= '1'; + elsif( CURRENT_STATE = E_RSTART ) then + e_rsf <= '1'; + elsif( CURRENT_STATE = E_ADDR ) then + e_anak <= '1'; + elsif( CURRENT_STATE = E_RADDR ) then + e_ranak <= '1'; + elsif( CURRENT_STATE = E_CMD ) then + e_cnak <= '1'; + elsif( CURRENT_STATE = E_WD ) then + e_dnak <= '1'; + end if; + end if; + end process THE_ERR_REG_PROC; + + status_out(7) <= running; + status_out(6) <= i2c_done; + status_out(5) <= e_ranak; + status_out(4) <= e_rsf; + status_out(3) <= e_dnak; + status_out(2) <= e_cnak; + status_out(1) <= e_anak; + status_out(0) <= e_sf; + +-- Outputs + i2c_dr_out <= i2c_dr(8 downto 1); + i2c_busy_out <= running; + +-- Debug stuff + stat(31 downto 28) <= (others => '0'); + stat(27) <= s_sda; + stat(26) <= r_sda; + stat(25) <= s_scl; + stat(24) <= r_scl; + stat(23) <= s_sda_sb; + stat(22) <= r_sda_sb; + stat(21) <= s_scl_sb; + stat(20) <= r_scl_sb; + stat(19) <= s_sda_gs; + stat(18) <= r_sda_gs; + stat(17) <= s_scl_gs; + stat(16) <= r_scl_gs; + stat(15 downto 12) <= gs_debug; + stat(11) <= bok; + stat(10) <= bdone; + stat(9) <= dobyte; + stat(8) <= sok; + stat(7) <= dobyte; + stat(6) <= s_sda_sb; + stat(5) <= r_sda_sb; + stat(4 downto 0) <= bsm; + + +end Behavioral; diff --git a/nxyter/source/nXyter.vhd b/nxyter/source/nXyter.vhd deleted file mode 100644 index ab70ae3..0000000 --- a/nxyter/source/nXyter.vhd +++ /dev/null @@ -1,46 +0,0 @@ ------------------------------------------------------------------------------ --- ---One nXyter FEB --- ------------------------------------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity nXyter_FEE_BOARD is - - port ( - CLK : in std_logic_vector; -- Clock - RESET : in std_logic_vector; -- RESET - - -- ADC - ADC_FCLK_IN : in std_logic; - ADC_DCLK_IN : in std_logic; - - SC_CLK32_IN : in std_logic; - - ADC_A_IN : in std_logic; - ADC_B_IN : in std_logic; - ADC_NX_IN : in std_logic; - ADC_D_IN : in std_logic; - - -- ADC SPI - CBS_OUT : out std_logic; - SDIO_MUX_OUT : out std_logic; - SCLK_OUT : out std_logic; - - -- nXyter - NX_CLK128_IN : in std_logic; - NX_IN : in std_logic_vector (7 downto 0); - RESET_OUT : out std_logic; - CLK256A_OUT : out std_logic; - TESTPULSE_OUT : out std_logic; - - -- I2C - SDA_MUX_OUT : out std_logic; - SCI_OUT : out std_logic; - I2C_RESET_OUT : out std_logic - REG_RESET : out std_logic - -end nXyter_FEE_BOARD; - diff --git a/nxyter/source/nxyter.vhd b/nxyter/source/nxyter.vhd new file mode 100644 index 0000000..b1a2a1b --- /dev/null +++ b/nxyter/source/nxyter.vhd @@ -0,0 +1,138 @@ +----------------------------------------------------------------------------- +-- +--One nXyter FEB +-- +----------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.adcmv3_components.all; + +entity nXyter_FEE_board is + + port ( + CLK_IN : in std_logic_vector; + RESET_IN : in std_logic_vector; + + -- I2C Ports + I2C_SDA_INOUT : inout std_logic; -- nXyter I2C fdata line + I2C_SCL_OUT : out std_logic; -- nXyter I2C Clock line + + I2C_SM_RESET_OUT : out std_logic; -- reset nXyter I2C StateMachine + I2C_REG_RESET_OUT : out std_logic; -- reset I2C registers to default + + -- ADC SPI + SPI_SCLK_OUT : out std_logic; + SPI_SDIO_INOUT : in std_logic; + SPI_CSB_OUT : out std_logic; + + -- nXyter Timestamp Ports + NX_CLK128_IN : in std_logic; + NX_IN : in std_logic_vector (7 downto 0); + NX_RESET_OUT : out std_logic; + NX_CLK256A_OUT : out std_logic; + NX_TESTPULSE_OUT : out std_logic; + + -- ADC nXyter Pulse Hight Ports + ADC_FCLK_IN : in std_logic; + ADC_DCLK_IN : in std_logic; + ADC_SC_CLK32_IN : in std_logic; + ADC_A_IN : in std_logic; + ADC_B_IN : in std_logic; + ADC_NX_IN : in std_logic; + ADC_D_IN : in std_logic; + + -- TRBNet RegIO Port for the slave bus + REGIO_ADDR_IN : in std_logic_vector(15 downto 0); + REGIO_DATA_IN : in std_logic_vector(31 downto 0); + REGIO_DATA_OUT : out std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN : in std_logic; + REGIO_WRITE_ENABLE_IN : in std_logic; + REGIO_TIMEOUT_IN : in std_logic; + REGIO_DATAREADY_OUT : out std_logic; + REGIO_WRITE_ACK_OUT : out std_logic; + REGIO_NO_MORE_DATA_OUT : out std_logic; + REGIO_UNKNOWN_ADDR_OUT : out std_logic + ); + +end nXyter_FEE_board; + + +architecture Behavioral of nXyter_FEE_board is + +------------------------------------------------------------------------------- +-- Signals +------------------------------------------------------------------------------- + + -- nXyter related signals + signal i2c_sda_o : std_logic; -- I2C SDA + signal i2c_sda_i : std_logic; + signal i2c_scl_o : std_logic; -- I2C SCL + signal i2c_scl_i : std_logic; + + signal spi_sdi : std_logic; + signal spi_sdo : std_logic; + + + +begin + +------------------------------------------------------------------------------- +-- Port Maps +------------------------------------------------------------------------------- + + -- slave bus signals + THE_SLAVE_BUS_1: slave_bus + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + + REGIO_ADDR_IN => REGIO_ADDR_IN, + REGIO_DATA_IN => REGIO_DATA_IN, + REGIO_DATA_OUT => REGIO_DATA_OUT, + REGIO_READ_ENABLE_IN => REGIO_READ_ENABLE_IN, + REGIO_WRITE_ENABLE_IN => REGIO_WRITE_ENABLE_IN, + REGIO_TIMEOUT_IN => REGIO_TIMEOUT_IN, + REGIO_DATAREADY_OUT => REGIO_DATAREADY_OUT, + REGIO_WRITE_ACK_OUT => REGIO_WRITE_ACK_OUT, + REGIO_NO_MORE_DATA_OUT => REGIO_NO_MORE_DATA_OUT, + REGIO_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT, + + SDA_IN => i2c_sda_i, + SDA_OUT => i2c_sda_o, + SCL_IN => i2c_scl_i, + SCL_OUT => i2c_scl_o, + + SPI_CS_OUT => SPI_CSB_OUT, + SPI_SCK_OUT => SPI_SCLK_OUT, + SPI_SDI_IN => spi_sdi, + SPI_SDO_OUT => spi_sdo + ); + + ----------------------------------------------------------------------------- + -- nXyter Signals + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- I2C Signals + ----------------------------------------------------------------------------- + + -- SDA line output + I2C_SDA_INOUT <= '0' when (i2c_sda_o = '0') else 'Z'; + + -- SDA line input (wired OR negative logic) + -- i2c_sda_i <= i2c_sda; + + -- SCL line output + I2C_SCL_OUT <= '0' when (i2c_scl_o = '0') else 'Z'; + + -- SCL line input (wired OR negative logic) + -- i2c_scl_i <= i2c_scl; + +------------------------------------------------------------------------------- +-- END +------------------------------------------------------------------------------- + +end Behavioral; diff --git a/nxyter/source/nxyter_components.vhd b/nxyter/source/nxyter_components.vhd new file mode 100644 index 0000000..2a64249 --- /dev/null +++ b/nxyter/source/nxyter_components.vhd @@ -0,0 +1,58 @@ +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.ALL; + +package nxyter_components is + +------------------------------------------------------------------------------- +-- TRBNet interfaces +------------------------------------------------------------------------------- + +component nXyter_FEE_board + port ( + CLK_IN : in std_logic_vector; + RESET_IN : in std_logic_vector; + I2C_SDA_INOUT : inout std_logic; + I2C_SCL_OUT : out std_logic; + I2C_SM_RESET_OUT : out std_logic; + I2C_REG_RESET_OUT : out std_logic; + SPI_SCLK_OUT : out std_logic; + SPI_SDIO_INOUT : in std_logic; + SPI_CSB_OUT : out std_logic; + NX_CLK128_IN : in std_logic; + NX_IN : in std_logic_vector (7 downto 0); + NX_RESET_OUT : out std_logic; + NX_CLK256A_OUT : out std_logic; + NX_TESTPULSE_OUT : out std_logic; + ADC_FCLK_IN : in std_logic; + ADC_DCLK_IN : in std_logic; + ADC_SC_CLK32_IN : in std_logic; + ADC_A_IN : in std_logic; + ADC_B_IN : in std_logic; + ADC_NX_IN : in std_logic; + ADC_D_IN : in std_logic; + REGIO_ADDR_IN : in std_logic_vector(15 downto 0); + REGIO_DATA_IN : in std_logic_vector(31 downto 0); + REGIO_DATA_OUT : out std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN : in std_logic; + REGIO_WRITE_ENABLE_IN : in std_logic; + REGIO_TIMEOUT_IN : in std_logic; + REGIO_DATAREADY_OUT : out std_logic; + REGIO_WRITE_ACK_OUT : out std_logic; + REGIO_NO_MORE_DATA_OUT : out std_logic; + REGIO_UNKNOWN_ADDR_OUT : out std_logic); +end component; + + + + + +component Gray_Decoder + generic ( + WIDTH : integer); + port ( + GRAY_IN : in std_logic_vector(WIDTH - 1 downto 0); + BINARY_OUT : out std_logic_vector(WIDTH - 1 downto 0)); +end component; + +end package; diff --git a/nxyter/source/slave_bus.vhd b/nxyter/source/slave_bus.vhd new file mode 100755 index 0000000..2925802 --- /dev/null +++ b/nxyter/source/slave_bus.vhd @@ -0,0 +1,840 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.adcmv3_components.all; + + +entity slave_bus is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- RegIO signals + REGIO_ADDR_IN : in std_logic_vector(15 downto 0); -- address bus + REGIO_DATA_IN : in std_logic_vector(31 downto 0); -- data from TRB endpoint + REGIO_DATA_OUT : out std_logic_vector(31 downto 0); -- data to TRB endpoint + REGIO_READ_ENABLE_IN : in std_logic; -- read pulse + REGIO_WRITE_ENABLE_IN : in std_logic; -- write pulse + REGIO_TIMEOUT_IN : in std_logic; -- access timed out + REGIO_DATAREADY_OUT : out std_logic; -- your data, master, as requested + REGIO_WRITE_ACK_OUT : out std_logic; -- data accepted + REGIO_NO_MORE_DATA_OUT : out std_logic; -- don't disturb me now + REGIO_UNKNOWN_ADDR_OUT : out std_logic; -- noone here to answer your request + + -- I2C connections + SDA_IN : in std_logic; + SDA_OUT : out std_logic; + SCL_IN : in std_logic; + SCL_OUT : out std_logic; + + -- SPI connections + SPI_CS_OUT : out std_logic; + SPI_SCK_OUT : out std_logic; + SPI_SDI_IN : in std_logic; + SPI_SDO_OUT : out std_logic + ); +end entity; + +architecture Behavioral of slave_bus is + +-- Signals + signal slv_read : std_logic_vector(18-1 downto 0); + signal slv_write : std_logic_vector(18-1 downto 0); + signal slv_busy : std_logic_vector(18-1 downto 0); + signal slv_ack : std_logic_vector(18-1 downto 0); + signal slv_addr : std_logic_vector(18*16-1 downto 0); + signal slv_data_rd : std_logic_vector(18*32-1 downto 0); + signal slv_data_wr : std_logic_vector(18*32-1 downto 0); + +-- SPI controller BRAM lines + signal spi_bram_addr : std_logic_vector(7 downto 0); + signal spi_bram_wr_d : std_logic_vector(7 downto 0); + signal spi_bram_rd_d : std_logic_vector(7 downto 0); + signal spi_bram_we : std_logic; + + signal spi_cs : std_logic; + signal spi_sck : std_logic; + signal spi_sdi : std_logic; + signal spi_sdo : std_logic; + signal spi_debug : std_logic_vector(31 downto 0); + + signal ctrl_lvl : std_logic_vector(31 downto 0); + signal ctrl_trg : std_logic_vector(31 downto 0); + signal ctrl_pll : std_logic_vector(15 downto 0); + + signal debug : std_logic_vector(63 downto 0); + signal onewire_debug : std_logic_vector(63 downto 0); + + -- do not know at the moment, have no backplanes, needed by Slave-Bus + signal bp_module_qq : std_logic_vector(3 downto 0); + + -- Pedestal and threshold stuff + type reg_18bit_t is array (0 to 15) of std_logic_vector(17 downto 0); + + signal buf_addr : std_logic_vector(6 downto 0); + signal thr_addr : std_logic_vector(6 downto 0); + signal thr_data : reg_18bit_t; + signal ped_data : reg_18bit_t; + +begin + +-- Bus handler: acts as bridge between RegIO and the FPGA internal slave bus + THE_BUS_HANDLER: trb_net16_regio_bus_handler + generic map( + PORT_NUMBER => 3, + PORT_ADDRESSES => ( 0 => x"a000", -- pedestal memories + 1 => x"a800", -- threshold memories + 2 => x"8040", -- I2C master + -- 3 => x"c000", -- 1Wire master + memory + -- 4 => x"d000", -- SPI master + -- 5 => x"d100", -- SPI data memory + -- 6 => x"d010", -- ADC0 SPI + -- 7 => x"d020", -- ADC1 SPI + -- 8 => x"b000", -- APV control / status + -- 9 => x"b010", -- ADC level settings + -- 10 => x"b020", -- trigger settings + -- 11 => x"b030", -- PLL settings + -- 12 => x"f000", -- ADC 0 snooper + -- 13 => x"f800", -- ADC 1 snooper + -- 14 => x"8000", -- test register (busy) + -- 15 => x"7100", -- data buffer status registers + -- 16 => x"7200", -- LVL1 release status register + -- 17 => x"7202", -- IPU handler status register + others => x"0000"), + PORT_ADDR_MASK => ( 0 => 16, -- pedestal memories + 1 => 16, -- threshold memories + 2 => 0, -- I2C master + -- 3 => 6, -- 1Wire master + memory + -- 4 => 1, -- SPI master + -- 5 => 6, -- SPI data memory + -- 6 => 0, -- ADC0 SPI + -- 7 => 0, -- ADC1 SPI + -- 8 => 4, -- APV control / status + -- 9 => 0, -- ADC level settings + -- 10 => 0, -- trigger settings + -- 11 => 0, -- PLL settings + -- 12 => 10, -- ADC 0 snooper + -- 13 => 10, -- ADC 1 snooper + -- 14 => 0, -- test register (normal) + -- 15 => 4, -- FIFO status registers + -- 16 => 0, -- LVL1 release status register + -- 17 => 0, -- IPU handler status register + others => 0) + ) + port map( + CLK => CLK_IN, + RESET => RESET_IN, + DAT_ADDR_IN => REGIO_ADDR_IN, + DAT_DATA_IN => REGIO_DATA_IN, + DAT_DATA_OUT => REGIO_DATA_OUT, + DAT_READ_ENABLE_IN => REGIO_READ_ENABLE_IN, + DAT_WRITE_ENABLE_IN => REGIO_WRITE_ENABLE_IN, + DAT_TIMEOUT_IN => REGIO_TIMEOUT_IN, + DAT_DATAREADY_OUT => REGIO_DATAREADY_OUT, + DAT_WRITE_ACK_OUT => REGIO_WRITE_ACK_OUT, + DAT_NO_MORE_DATA_OUT => REGIO_NO_MORE_DATA_OUT, + DAT_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT, + -- pedestal memories + BUS_READ_ENABLE_OUT(0) => slv_read(0), + BUS_WRITE_ENABLE_OUT(0) => slv_write(0), + BUS_DATA_OUT(0*32+31 downto 0*32) => slv_data_wr(0*32+31 downto 0*32), + BUS_DATA_IN(0*32+31 downto 0*32) => slv_data_rd(0*32+31 downto 0*32), + BUS_ADDR_OUT(0*16+15 downto 0*16) => slv_addr(0*16+15 downto 0*16), + BUS_TIMEOUT_OUT(0) => open, + BUS_DATAREADY_IN(0) => slv_ack(0), + BUS_WRITE_ACK_IN(0) => slv_ack(0), + BUS_NO_MORE_DATA_IN(0) => slv_busy(0), + BUS_UNKNOWN_ADDR_IN(0) => '0', + -- threshold memories + BUS_READ_ENABLE_OUT(1) => slv_read(1), + BUS_WRITE_ENABLE_OUT(1) => slv_write(1), + BUS_DATA_OUT(1*32+31 downto 1*32) => slv_data_wr(1*32+31 downto 1*32), + BUS_DATA_IN(1*32+31 downto 1*32) => slv_data_rd(1*32+31 downto 1*32), + BUS_ADDR_OUT(1*16+15 downto 1*16) => slv_addr(1*16+15 downto 1*16), + BUS_TIMEOUT_OUT(1) => open, + BUS_DATAREADY_IN(1) => slv_ack(1), + BUS_WRITE_ACK_IN(1) => slv_ack(1), + BUS_NO_MORE_DATA_IN(1) => slv_busy(1), + BUS_UNKNOWN_ADDR_IN(1) => '0', + -- I2C master + BUS_READ_ENABLE_OUT(2) => slv_read(2), + BUS_WRITE_ENABLE_OUT(2) => slv_write(2), + BUS_DATA_OUT(2*32+31 downto 2*32) => slv_data_wr(2*32+31 downto 2*32), + BUS_DATA_IN(2*32+31 downto 2*32) => slv_data_rd(2*32+31 downto 2*32), + BUS_ADDR_OUT(2*16+15 downto 2*16) => open, + BUS_TIMEOUT_OUT(2) => open, + BUS_DATAREADY_IN(2) => slv_ack(2), + BUS_WRITE_ACK_IN(2) => slv_ack(2), + BUS_NO_MORE_DATA_IN(2) => slv_busy(2), + BUS_UNKNOWN_ADDR_IN(2) => '0', + + -- OneWire master + --BUS_READ_ENABLE_OUT(3) => slv_read(3), + --BUS_WRITE_ENABLE_OUT(3) => slv_write(3), + --BUS_DATA_OUT(3*32+31 downto 3*32) => slv_data_wr(3*32+31 downto 3*32), + --BUS_DATA_IN(3*32+31 downto 3*32) => slv_data_rd(3*32+31 downto 3*32), + --BUS_ADDR_OUT(3*16+15 downto 3*16) => slv_addr(3*16+15 downto 3*16), + --BUS_TIMEOUT_OUT(3) => open, + --BUS_DATAREADY_IN(3) => slv_ack(3), + --BUS_WRITE_ACK_IN(3) => slv_ack(3), + --BUS_NO_MORE_DATA_IN(3) => slv_busy(3), + --BUS_UNKNOWN_ADDR_IN(3) => '0', + ---- SPI control registers + --BUS_READ_ENABLE_OUT(4) => slv_read(4), + --BUS_WRITE_ENABLE_OUT(4) => slv_write(4), + --BUS_DATA_OUT(4*32+31 downto 4*32) => slv_data_wr(4*32+31 downto 4*32), + --BUS_DATA_IN(4*32+31 downto 4*32) => slv_data_rd(4*32+31 downto 4*32), + --BUS_ADDR_OUT(4*16+15 downto 4*16) => slv_addr(4*16+15 downto 4*16), + --BUS_TIMEOUT_OUT(4) => open, + --BUS_DATAREADY_IN(4) => slv_ack(4), + --BUS_WRITE_ACK_IN(4) => slv_ack(4), + --BUS_NO_MORE_DATA_IN(4) => slv_busy(4), + --BUS_UNKNOWN_ADDR_IN(4) => '0', + ---- SPI data memory + --BUS_READ_ENABLE_OUT(5) => slv_read(5), + --BUS_WRITE_ENABLE_OUT(5) => slv_write(5), + --BUS_DATA_OUT(5*32+31 downto 5*32) => slv_data_wr(5*32+31 downto 5*32), + --BUS_DATA_IN(5*32+31 downto 5*32) => slv_data_rd(5*32+31 downto 5*32), + --BUS_ADDR_OUT(5*16+15 downto 5*16) => slv_addr(5*16+15 downto 5*16), + --BUS_TIMEOUT_OUT(5) => open, + --BUS_DATAREADY_IN(5) => slv_ack(5), + --BUS_WRITE_ACK_IN(5) => slv_ack(5), + --BUS_NO_MORE_DATA_IN(5) => slv_busy(5), + --BUS_UNKNOWN_ADDR_IN(5) => '0', + ---- ADC 0 SPI control registers + --BUS_READ_ENABLE_OUT(6) => slv_read(6), + --BUS_WRITE_ENABLE_OUT(6) => slv_write(6), + --BUS_DATA_OUT(6*32+31 downto 6*32) => slv_data_wr(6*32+31 downto 6*32), + --BUS_DATA_IN(6*32+31 downto 6*32) => slv_data_rd(6*32+31 downto 6*32), + --BUS_ADDR_OUT(6*16+15 downto 6*16) => open, + --BUS_TIMEOUT_OUT(6) => open, + --BUS_DATAREADY_IN(6) => slv_ack(6), + --BUS_WRITE_ACK_IN(6) => slv_ack(6), + --BUS_NO_MORE_DATA_IN(6) => slv_busy(6), + --BUS_UNKNOWN_ADDR_IN(6) => '0', + ---- ADC 1 SPI control registers + --BUS_READ_ENABLE_OUT(7) => slv_read(7), + --BUS_WRITE_ENABLE_OUT(7) => slv_write(7), + --BUS_DATA_OUT(7*32+31 downto 7*32) => slv_data_wr(7*32+31 downto 7*32), + --BUS_DATA_IN(7*32+31 downto 7*32) => slv_data_rd(7*32+31 downto 7*32), + --BUS_ADDR_OUT(7*16+15 downto 7*16) => open, + --BUS_TIMEOUT_OUT(7) => open, + --BUS_DATAREADY_IN(7) => slv_ack(7), + --BUS_WRITE_ACK_IN(7) => slv_ack(7), + --BUS_NO_MORE_DATA_IN(7) => slv_busy(7), + --BUS_UNKNOWN_ADDR_IN(7) => '0', + ---- APV control / status registers + --BUS_READ_ENABLE_OUT(8) => slv_read(8), + --BUS_WRITE_ENABLE_OUT(8) => slv_write(8), + --BUS_DATA_OUT(8*32+31 downto 8*32) => slv_data_wr(8*32+31 downto 8*32), + --BUS_DATA_IN(8*32+31 downto 8*32) => slv_data_rd(8*32+31 downto 8*32), + --BUS_ADDR_OUT(8*16+15 downto 8*16) => slv_addr(8*16+15 downto 8*16), + --BUS_TIMEOUT_OUT(8) => open, + --BUS_DATAREADY_IN(8) => slv_ack(8), + --BUS_WRITE_ACK_IN(8) => slv_ack(8), + --BUS_NO_MORE_DATA_IN(8) => slv_busy(8), + --BUS_UNKNOWN_ADDR_IN(8) => '0', + ---- ADC / PLL / trigger ctrl register + --BUS_READ_ENABLE_OUT(11 downto 9) => slv_read(11 downto 9), + --BUS_WRITE_ENABLE_OUT(11 downto 9) => slv_write(11 downto 9), + --BUS_DATA_OUT(11*32+31 downto 9*32) => slv_data_wr(11*32+31 downto 9*32), + --BUS_DATA_IN(11*32+31 downto 9*32) => slv_data_rd(11*32+31 downto 9*32), + --BUS_ADDR_OUT(11*16+15 downto 9*16) => open, + --BUS_TIMEOUT_OUT(11 downto 9) => open, + --BUS_DATAREADY_IN(11 downto 9) => slv_ack(11 downto 9), + --BUS_WRITE_ACK_IN(11 downto 9) => slv_ack(11 downto 9), + --BUS_NO_MORE_DATA_IN(11 downto 9) => slv_busy(11 downto 9), + --BUS_UNKNOWN_ADDR_IN(11 downto 9) => (others => '0'), + ---- ADC0 snooper + --BUS_READ_ENABLE_OUT(12) => slv_read(12), + --BUS_WRITE_ENABLE_OUT(12) => slv_write(12), + --BUS_DATA_OUT(12*32+31 downto 12*32) => slv_data_wr(12*32+31 downto 12*32), + --BUS_DATA_IN(12*32+31 downto 12*32) => slv_data_rd(12*32+31 downto 12*32), + --BUS_ADDR_OUT(12*16+15 downto 12*16) => slv_addr(12*16+15 downto 12*16), + --BUS_TIMEOUT_OUT(12) => open, + --BUS_DATAREADY_IN(12) => slv_ack(12), + --BUS_WRITE_ACK_IN(12) => slv_ack(12), + --BUS_NO_MORE_DATA_IN(12) => slv_busy(12), + --BUS_UNKNOWN_ADDR_IN(12) => '0', + ---- ADC1 snooper + --BUS_READ_ENABLE_OUT(13) => slv_read(13), + --BUS_WRITE_ENABLE_OUT(13) => slv_write(13), + --BUS_DATA_OUT(13*32+31 downto 13*32) => slv_data_wr(13*32+31 downto 13*32), + --BUS_DATA_IN(13*32+31 downto 13*32) => slv_data_rd(13*32+31 downto 13*32), + --BUS_ADDR_OUT(13*16+15 downto 13*16) => slv_addr(13*16+15 downto 13*16), + --BUS_TIMEOUT_OUT(13) => open, + --BUS_DATAREADY_IN(13) => slv_ack(13), + --BUS_WRITE_ACK_IN(13) => slv_ack(13), + --BUS_NO_MORE_DATA_IN(13) => slv_busy(13), + --BUS_UNKNOWN_ADDR_IN(13) => '0', + ---- Test register + --BUS_READ_ENABLE_OUT(14) => slv_read(14), + --BUS_WRITE_ENABLE_OUT(14) => slv_write(14), + --BUS_DATA_OUT(14*32+31 downto 14*32) => slv_data_wr(14*32+31 downto 14*32), + --BUS_DATA_IN(14*32+31 downto 14*32) => slv_data_rd(14*32+31 downto 14*32), + --BUS_ADDR_OUT(14*16+15 downto 14*16) => open, + --BUS_TIMEOUT_OUT(14) => open, + --BUS_DATAREADY_IN(14) => slv_ack(14), + --BUS_WRITE_ACK_IN(14) => slv_ack(14), + --BUS_NO_MORE_DATA_IN(14) => slv_busy(14), + --BUS_UNKNOWN_ADDR_IN(14) => '0', + ---- data buffer status registers + --BUS_READ_ENABLE_OUT(15) => slv_read(15), + --BUS_WRITE_ENABLE_OUT(15) => slv_write(15), + --BUS_DATA_OUT(15*32+31 downto 15*32) => slv_data_wr(15*32+31 downto 15*32), + --BUS_DATA_IN(15*32+31 downto 15*32) => slv_data_rd(15*32+31 downto 15*32), + --BUS_ADDR_OUT(15*16+15 downto 15*16) => slv_addr(15*16+15 downto 15*16), + --BUS_TIMEOUT_OUT(15) => open, + --BUS_DATAREADY_IN(15) => slv_ack(15), + --BUS_WRITE_ACK_IN(15) => slv_ack(15), + --BUS_NO_MORE_DATA_IN(15) => slv_busy(15), + --BUS_UNKNOWN_ADDR_IN(15) => '0', + ---- LVL1 release status register + --BUS_READ_ENABLE_OUT(16) => slv_read(16), + --BUS_WRITE_ENABLE_OUT(16) => slv_write(16), + --BUS_DATA_OUT(16*32+31 downto 16*32) => slv_data_wr(16*32+31 downto 16*32), + --BUS_DATA_IN(16*32+31 downto 16*32) => slv_data_rd(16*32+31 downto 16*32), + --BUS_ADDR_OUT(16*16+15 downto 16*16) => slv_addr(16*16+15 downto 16*16), + --BUS_TIMEOUT_OUT(16) => open, + --BUS_DATAREADY_IN(16) => slv_ack(16), + --BUS_WRITE_ACK_IN(16) => slv_ack(16), + --BUS_NO_MORE_DATA_IN(16) => slv_busy(16), + --BUS_UNKNOWN_ADDR_IN(16) => '0', + ---- IPU handler status register + --BUS_READ_ENABLE_OUT(17) => slv_read(17), + --BUS_WRITE_ENABLE_OUT(17) => slv_write(17), + --BUS_DATA_OUT(17*32+31 downto 17*32) => slv_data_wr(17*32+31 downto 17*32), + --BUS_DATA_IN(17*32+31 downto 17*32) => slv_data_rd(17*32+31 downto 17*32), + --BUS_ADDR_OUT(17*16+15 downto 17*16) => slv_addr(17*16+15 downto 17*16), + --BUS_TIMEOUT_OUT(17) => open, + --BUS_DATAREADY_IN(17) => slv_ack(17), + --BUS_WRITE_ACK_IN(17) => slv_ack(17), + --BUS_NO_MORE_DATA_IN(17) => slv_busy(17), + --BUS_UNKNOWN_ADDR_IN(17) => '0', + ---- debug + --STAT_DEBUG => stat + STAT_DEBUG => open + ); + + +------------------------------------------------------------------------------------ +-- pedestal memories (16x128 = 2048, 18bit) +------------------------------------------------------------------------------------ + THE_PED_MEM: slv_ped_thr_mem + port map( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + -- Slave bus + SLV_ADDR_IN => slv_addr(0*16+10 downto 0*16), + SLV_READ_IN => slv_read(0), + SLV_WRITE_IN => slv_write(0), + SLV_ACK_OUT => slv_ack(0), + SLV_DATA_IN => slv_data_wr(0*32+31 downto 0*32), + SLV_DATA_OUT => slv_data_rd(0*32+31 downto 0*32), + -- backplane identifier + BACKPLANE_IN => bp_module_qq, + -- I/O to the backend + MEM_CLK_IN => CLK_IN, + MEM_ADDR_IN => buf_addr, + MEM_0_D_OUT => ped_data(0), + MEM_1_D_OUT => ped_data(1), + MEM_2_D_OUT => ped_data(2), + MEM_3_D_OUT => ped_data(3), + MEM_4_D_OUT => ped_data(4), + MEM_5_D_OUT => ped_data(5), + MEM_6_D_OUT => ped_data(6), + MEM_7_D_OUT => ped_data(7), + MEM_8_D_OUT => ped_data(8), + MEM_9_D_OUT => ped_data(9), + MEM_10_D_OUT => ped_data(10), + MEM_11_D_OUT => ped_data(11), + MEM_12_D_OUT => ped_data(12), + MEM_13_D_OUT => ped_data(13), + MEM_14_D_OUT => ped_data(14), + MEM_15_D_OUT => ped_data(15), + -- Status lines + STAT => open + ); + slv_busy(0) <= '0'; + +------------------------------------------------------------------------------------ +-- threshold memories (16x128 = 2048, 18bit) +------------------------------------------------------------------------------------ + THE_THR_MEM: slv_ped_thr_mem + port map( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + -- Slave bus + SLV_ADDR_IN => slv_addr(1*16+10 downto 1*16), + SLV_READ_IN => slv_read(1), + SLV_WRITE_IN => slv_write(1), + SLV_ACK_OUT => slv_ack(1), + SLV_DATA_IN => slv_data_wr(1*32+31 downto 1*32), + SLV_DATA_OUT => slv_data_rd(1*32+31 downto 1*32), + -- backplane identifier + BACKPLANE_IN => bp_module_qq, + -- I/O to the backend + MEM_CLK_IN => CLK_IN, + MEM_ADDR_IN => thr_addr, + MEM_0_D_OUT => thr_data(0), + MEM_1_D_OUT => thr_data(1), + MEM_2_D_OUT => thr_data(2), + MEM_3_D_OUT => thr_data(3), + MEM_4_D_OUT => thr_data(4), + MEM_5_D_OUT => thr_data(5), + MEM_6_D_OUT => thr_data(6), + MEM_7_D_OUT => thr_data(7), + MEM_8_D_OUT => thr_data(8), + MEM_9_D_OUT => thr_data(9), + MEM_10_D_OUT => thr_data(10), + MEM_11_D_OUT => thr_data(11), + MEM_12_D_OUT => thr_data(12), + MEM_13_D_OUT => thr_data(13), + MEM_14_D_OUT => thr_data(14), + MEM_15_D_OUT => thr_data(15), + -- Status lines + STAT => open + ); + slv_busy(1) <= '0'; + +------------------------------------------------------------------------------------ +-- I2C master block for accessing APVs +------------------------------------------------------------------------------------ + THE_I2C_MASTER: i2c_master + port map( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + -- Slave bus + SLV_READ_IN => slv_read(2), + SLV_WRITE_IN => slv_write(2), + SLV_BUSY_OUT => slv_busy(2), + SLV_ACK_OUT => slv_ack(2), + SLV_DATA_IN => slv_data_wr(2*32+31 downto 2*32), + SLV_DATA_OUT => slv_data_rd(2*32+31 downto 2*32), + -- I2C connections + SDA_IN => SDA_IN, + SDA_OUT => SDA_OUT, + SCL_IN => SCL_IN, + SCL_OUT => SCL_OUT, + -- Status lines + STAT => open + ); + +-- ------------------------------------------------------------------------------------ +-- -- SPI master +-- ------------------------------------------------------------------------------------ +-- THE_SPI_MASTER: spi_master +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- BUS_READ_IN => slv_read(4), +-- BUS_WRITE_IN => slv_write(4), +-- BUS_BUSY_OUT => slv_busy(4), +-- BUS_ACK_OUT => slv_ack(4), +-- BUS_ADDR_IN => slv_addr(4*16+0 downto 4*16), +-- BUS_DATA_IN => slv_data_wr(4*32+31 downto 4*32), +-- BUS_DATA_OUT => slv_data_rd(4*32+31 downto 4*32), +-- -- SPI connections +-- SPI_CS_OUT => spi_cs, +-- SPI_SDI_IN => spi_sdi, +-- SPI_SDO_OUT => spi_sdo, +-- SPI_SCK_OUT => spi_sck, +-- -- BRAM for read/write data +-- BRAM_A_OUT => spi_bram_addr, +-- BRAM_WR_D_IN => spi_bram_wr_d, +-- BRAM_RD_D_OUT => spi_bram_rd_d, +-- BRAM_WE_OUT => spi_bram_we, +-- -- Status lines +-- STAT => spi_debug --open +-- ); +-- +-- ------------------------------------------------------------------------------------ +-- -- data memory for SPI accesses +-- ------------------------------------------------------------------------------------ +-- THE_SPI_MEMORY: spi_databus_memory +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- BUS_ADDR_IN => slv_addr(5*16+5 downto 5*16), +-- BUS_READ_IN => slv_read(5), +-- BUS_WRITE_IN => slv_write(5), +-- BUS_ACK_OUT => slv_ack(5), +-- BUS_DATA_IN => slv_data_wr(5*32+31 downto 5*32), +-- BUS_DATA_OUT => slv_data_rd(5*32+31 downto 5*32), +-- -- state machine connections +-- BRAM_ADDR_IN => spi_bram_addr, +-- BRAM_WR_D_OUT => spi_bram_wr_d, +-- BRAM_RD_D_IN => spi_bram_rd_d, +-- BRAM_WE_IN => spi_bram_we, +-- -- Status lines +-- STAT => open +-- ); +-- slv_busy(5) <= '0'; +-- +-- ------------------------------------------------------------------------------------ +-- -- ADC0 SPI master +-- ------------------------------------------------------------------------------------ +-- THE_SPI_ADC0_MASTER: spi_adc_master +-- generic map( +-- RESET_VALUE_CTRL => x"60" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_READ_IN => slv_read(6), +-- SLV_WRITE_IN => slv_write(6), +-- SLV_BUSY_OUT => slv_busy(6), +-- SLV_ACK_OUT => slv_ack(6), +-- SLV_DATA_IN => slv_data_wr(6*32+31 downto 6*32), +-- SLV_DATA_OUT => slv_data_rd(6*32+31 downto 6*32), +-- -- SPI connections +-- SPI_CS_OUT => SPI_ADC0_CS_OUT, +-- SPI_SDO_OUT => SPI_ADC0_SDO_OUT, +-- SPI_SCK_OUT => SPI_ADC0_SCK_OUT, +-- -- ADC connections +-- ADC_LOCKED_IN => ADC0_PLL_LOCKED_IN, +-- ADC_PD_OUT => ADC0_PD_OUT, +-- ADC_RST_OUT => ADC0_RST_OUT, +-- ADC_DEL_OUT => ADC0_DEL_OUT, +-- -- APV connections +-- APV_RST_OUT => APV0_RST_OUT, +-- -- Status lines +-- STAT => open +-- ); +-- +-- ------------------------------------------------------------------------------------ +-- -- ADC1 SPI master +-- ------------------------------------------------------------------------------------ +-- THE_SPI_ADC1_MASTER: spi_adc_master +-- generic map( +-- RESET_VALUE_CTRL => x"60" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_READ_IN => slv_read(7), +-- SLV_WRITE_IN => slv_write(7), +-- SLV_BUSY_OUT => slv_busy(7), +-- SLV_ACK_OUT => slv_ack(7), +-- SLV_DATA_IN => slv_data_wr(7*32+31 downto 7*32), +-- SLV_DATA_OUT => slv_data_rd(7*32+31 downto 7*32), +-- -- SPI connections +-- SPI_CS_OUT => SPI_ADC1_CS_OUT, +-- SPI_SDO_OUT => SPI_ADC1_SDO_OUT, +-- SPI_SCK_OUT => SPI_ADC1_SCK_OUT, +-- -- ADC connections +-- ADC_LOCKED_IN => ADC1_PLL_LOCKED_IN, +-- ADC_PD_OUT => ADC1_PD_OUT, +-- ADC_RST_OUT => ADC1_RST_OUT, +-- ADC_DEL_OUT => ADC1_DEL_OUT, +-- -- APV connections +-- APV_RST_OUT => APV1_RST_OUT, +-- -- Status lines +-- STAT => open +-- ); +-- +-- ------------------------------------------------------------------------------------ +-- -- APV control / status registers +-- ------------------------------------------------------------------------------------ +-- THE_SLV_REGISTER_BANK: slv_register_bank +-- generic map( +-- RESET_VALUE => x"0001" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_ADDR_IN => slv_addr(8*16+3 downto 8*16), +-- SLV_READ_IN => slv_read(8), +-- SLV_WRITE_IN => slv_write(8), +-- SLV_ACK_OUT => slv_ack(8), +-- SLV_DATA_IN => slv_data_wr(8*32+31 downto 8*32), +-- SLV_DATA_OUT => slv_data_rd(8*32+31 downto 8*32), +-- -- I/O to the backend +-- BACKPLANE_IN => BACKPLANE_IN, +-- CTRL_0_OUT => CTRL_0_OUT, +-- CTRL_1_OUT => CTRL_1_OUT, +-- CTRL_2_OUT => CTRL_2_OUT, +-- CTRL_3_OUT => CTRL_3_OUT, +-- CTRL_4_OUT => CTRL_4_OUT, +-- CTRL_5_OUT => CTRL_5_OUT, +-- CTRL_6_OUT => CTRL_6_OUT, +-- CTRL_7_OUT => CTRL_7_OUT, +-- CTRL_8_OUT => CTRL_8_OUT, +-- CTRL_9_OUT => CTRL_9_OUT, +-- CTRL_10_OUT => CTRL_10_OUT, +-- CTRL_11_OUT => CTRL_11_OUT, +-- CTRL_12_OUT => CTRL_12_OUT, +-- CTRL_13_OUT => CTRL_13_OUT, +-- CTRL_14_OUT => CTRL_14_OUT, +-- CTRL_15_OUT => CTRL_15_OUT, +-- STAT_0_IN => STAT_0_IN, +-- STAT_1_IN => STAT_1_IN, +-- STAT_2_IN => STAT_2_IN, +-- STAT_3_IN => STAT_3_IN, +-- STAT_4_IN => STAT_4_IN, +-- STAT_5_IN => STAT_5_IN, +-- STAT_6_IN => STAT_6_IN, +-- STAT_7_IN => STAT_7_IN, +-- STAT_8_IN => STAT_8_IN, +-- STAT_9_IN => STAT_9_IN, +-- STAT_10_IN => STAT_10_IN, +-- STAT_11_IN => STAT_11_IN, +-- STAT_12_IN => STAT_12_IN, +-- STAT_13_IN => STAT_13_IN, +-- STAT_14_IN => STAT_14_IN, +-- STAT_15_IN => STAT_15_IN, +-- -- Status lines +-- STAT => open +-- ); +-- slv_busy(8) <= '0'; +-- +-- ------------------------------------------------------------------------------------ +-- -- Data buffer status registers +-- ------------------------------------------------------------------------------------ +-- THE_FIFO_STATUS_BANK: slv_status_bank +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_ADDR_IN => slv_addr(15*16+3 downto 15*16), +-- SLV_READ_IN => slv_read(15), +-- SLV_WRITE_IN => slv_write(15), +-- SLV_ACK_OUT => slv_ack(15), +-- SLV_DATA_OUT => slv_data_rd(15*32+31 downto 15*32), +-- -- I/O to the backend +-- STAT_0_IN => FIFO_STATUS_0_IN, +-- STAT_1_IN => FIFO_STATUS_1_IN, +-- STAT_2_IN => FIFO_STATUS_2_IN, +-- STAT_3_IN => FIFO_STATUS_3_IN, +-- STAT_4_IN => FIFO_STATUS_4_IN, +-- STAT_5_IN => FIFO_STATUS_5_IN, +-- STAT_6_IN => FIFO_STATUS_6_IN, +-- STAT_7_IN => FIFO_STATUS_7_IN, +-- STAT_8_IN => FIFO_STATUS_8_IN, +-- STAT_9_IN => FIFO_STATUS_9_IN, +-- STAT_10_IN => FIFO_STATUS_10_IN, +-- STAT_11_IN => FIFO_STATUS_11_IN, +-- STAT_12_IN => FIFO_STATUS_12_IN, +-- STAT_13_IN => FIFO_STATUS_13_IN, +-- STAT_14_IN => FIFO_STATUS_14_IN, +-- STAT_15_IN => FIFO_STATUS_15_IN +-- ); +-- slv_busy(15) <= '0'; +-- +-- +-- ------------------------------------------------------------------------------------ +-- -- LVL1 release status +-- ------------------------------------------------------------------------------------ +-- THE_LVL1_RELEASE_STATUS: slv_status +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_READ_IN => slv_read(16), +-- SLV_WRITE_IN => slv_write(16), +-- SLV_ACK_OUT => slv_ack(16), +-- SLV_DATA_OUT => slv_data_rd(16*32+31 downto 16*32), +-- -- I/O to the backend +-- STATUS_IN => RELEASE_STATUS_IN +-- ); +-- slv_busy(16) <= '0'; +-- +-- +-- ------------------------------------------------------------------------------------ +-- -- IPU handler status +-- ------------------------------------------------------------------------------------ +-- THE_IPU_HANDLER_STATUS: slv_status +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_READ_IN => slv_read(17), +-- SLV_WRITE_IN => slv_write(17), +-- SLV_ACK_OUT => slv_ack(17), +-- SLV_DATA_OUT => slv_data_rd(17*32+31 downto 17*32), +-- -- I/O to the backend +-- STATUS_IN => IPU_STATUS_IN +-- ); +-- slv_busy(17) <= '0'; +-- +-- +-- ------------------------------------------------------------------------------------ +-- -- ADC level register +-- ------------------------------------------------------------------------------------ +-- THE_ADC_LVL_REG: slv_register +-- generic map( +-- RESET_VALUE => x"d0_20_88_78" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, -- general reset +-- BUSY_IN => '0', +-- -- Slave bus +-- SLV_READ_IN => slv_read(9), +-- SLV_WRITE_IN => slv_write(9), +-- SLV_BUSY_OUT => slv_busy(9), +-- SLV_ACK_OUT => slv_ack(9), +-- SLV_DATA_IN => slv_data_wr(9*32+31 downto 9*32), +-- SLV_DATA_OUT => slv_data_rd(9*32+31 downto 9*32), +-- -- I/O to the backend +-- REG_DATA_IN => ctrl_lvl, +-- REG_DATA_OUT => ctrl_lvl, +-- -- Status lines +-- STAT => open +-- ); +-- +-- ------------------------------------------------------------------------------------ +-- -- trigger control register +-- ------------------------------------------------------------------------------------ +-- THE_TRG_CTRL_REG: slv_register +-- generic map( +-- RESET_VALUE => x"10_10_10_10" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, -- general reset +-- BUSY_IN => '0', +-- -- Slave bus +-- SLV_READ_IN => slv_read(10), +-- SLV_WRITE_IN => slv_write(10), +-- SLV_BUSY_OUT => slv_busy(10), +-- SLV_ACK_OUT => slv_ack(10), +-- SLV_DATA_IN => slv_data_wr(10*32+31 downto 10*32), +-- SLV_DATA_OUT => slv_data_rd(10*32+31 downto 10*32), +-- -- I/O to the backend +-- REG_DATA_IN => ctrl_trg, +-- REG_DATA_OUT => ctrl_trg, +-- -- Status lines +-- STAT => open +-- ); +-- +-- ------------------------------------------------------------------------------------ +-- -- PLL control register +-- ------------------------------------------------------------------------------------ +-- THE_PLL_CTRL_REG: slv_half_register +-- generic map( +-- RESET_VALUE => x"00_02" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, -- general reset +-- -- Slave bus +-- SLV_READ_IN => slv_read(11), +-- SLV_WRITE_IN => slv_write(11), +-- SLV_ACK_OUT => slv_ack(11), +-- SLV_DATA_IN => slv_data_wr(11*32+31 downto 11*32), +-- SLV_DATA_OUT => slv_data_rd(11*32+31 downto 11*32), +-- -- I/O to the backend +-- STATUS_REG_IN => STATUS_PLL_IN, +-- CTRL_REG_OUT => ctrl_pll, +-- -- Status lines +-- STAT => open +-- ); +-- slv_busy(11) <= '0'; +-- +-- ------------------------------------------------------------------------------------ +-- -- ADC0 snooper +-- ------------------------------------------------------------------------------------ +-- THE_ADC0_SNOOPER: slv_adc_snoop +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_ADDR_IN => slv_addr(12*16+9 downto 12*16), +-- SLV_READ_IN => slv_read(12), +-- SLV_WRITE_IN => slv_write(12), +-- SLV_ACK_OUT => slv_ack(12), +-- SLV_DATA_IN => slv_data_wr(12*32+31 downto 12*32), +-- SLV_DATA_OUT => slv_data_rd(12*32+31 downto 12*32), +-- -- I/O to the backend +-- ADC_SEL_OUT => ADC0_SEL_OUT, +-- ADC_CLK_IN => ADC0_CLK_IN, +-- ADC_DATA_IN => ADC0_DATA_IN, +-- -- Status lines +-- STAT => open +-- ); +-- slv_busy(12) <= '0'; +-- +-- +-- ------------------------------------------------------------------------------------ +-- -- ADC1 snooper +-- ------------------------------------------------------------------------------------ +-- THE_ADC1_SNOOPER: slv_adc_snoop +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, +-- -- Slave bus +-- SLV_ADDR_IN => slv_addr(13*16+9 downto 13*16), +-- SLV_READ_IN => slv_read(13), +-- SLV_WRITE_IN => slv_write(13), +-- SLV_ACK_OUT => slv_ack(13), +-- SLV_DATA_IN => slv_data_wr(13*32+31 downto 13*32), +-- SLV_DATA_OUT => slv_data_rd(13*32+31 downto 13*32), +-- -- I/O to the backend +-- ADC_SEL_OUT => ADC1_SEL_OUT, +-- ADC_CLK_IN => ADC1_CLK_IN, +-- ADC_DATA_IN => ADC1_DATA_IN, +-- -- Status lines +-- STAT => open +-- ); +-- slv_busy(13) <= '0'; +-- +-- +-- ------------------------------------------------------------------------------------ +-- -- test register (normal) +-- ------------------------------------------------------------------------------------ +-- THE_GOOD_TEST_REG: slv_register +-- generic map( +-- RESET_VALUE => x"dead_beef" +-- ) +-- port map( +-- CLK_IN => CLK_IN, +-- RESET_IN => RESET_IN, -- general reset +-- BUSY_IN => '0', +-- -- Slave bus +-- SLV_READ_IN => slv_read(14), +-- SLV_WRITE_IN => slv_write(14), +-- SLV_BUSY_OUT => slv_busy(14), +-- SLV_ACK_OUT => slv_ack(14), +-- SLV_DATA_IN => slv_data_wr(14*32+31 downto 14*32), +-- SLV_DATA_OUT => slv_data_rd(14*32+31 downto 14*32), +-- -- I/O to the backend +-- REG_DATA_IN => TEST_REG_IN, --x"5a3c_87e1", +-- REG_DATA_OUT => TEST_REG_OUT, +-- -- Status lines +-- STAT => open +-- ); +-- +-- + + +-- unusable pins + debug(63 downto 43) <= (others => '0'); +-- connected pins + debug(42 downto 0) <= (others => '0'); + +-- input signals + spi_sdi <= SPI_SDI_IN; + +-- Output signals + SPI_CS_OUT <= spi_cs; + SPI_SCK_OUT <= spi_sck; + SPI_SDO_OUT <= spi_sdo; + + -- CTRL_LVL_OUT <= ctrl_lvl; + -- CTRL_TRG_OUT <= ctrl_trg; + -- CTRL_PLL_OUT <= ctrl_pll; + + -- DEBUG_OUT <= debug; + +end Behavioral; diff --git a/nxyter/source/slv_ped_thr_mem.vhd b/nxyter/source/slv_ped_thr_mem.vhd new file mode 100644 index 0000000..340fdfd --- /dev/null +++ b/nxyter/source/slv_ped_thr_mem.vhd @@ -0,0 +1,265 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv3_components.all; + +entity slv_ped_thr_mem is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- Slave bus + SLV_ADDR_IN : in std_logic_vector(10 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + + -- backplane identifier + BACKPLANE_IN : in std_logic_vector(2 downto 0); + + -- I/O to the backend + MEM_CLK_IN : in std_logic; + MEM_ADDR_IN : in std_logic_vector(6 downto 0); + MEM_0_D_OUT : out std_logic_vector(17 downto 0); + MEM_1_D_OUT : out std_logic_vector(17 downto 0); + MEM_2_D_OUT : out std_logic_vector(17 downto 0); + MEM_3_D_OUT : out std_logic_vector(17 downto 0); + MEM_4_D_OUT : out std_logic_vector(17 downto 0); + MEM_5_D_OUT : out std_logic_vector(17 downto 0); + MEM_6_D_OUT : out std_logic_vector(17 downto 0); + MEM_7_D_OUT : out std_logic_vector(17 downto 0); + MEM_8_D_OUT : out std_logic_vector(17 downto 0); + MEM_9_D_OUT : out std_logic_vector(17 downto 0); + MEM_10_D_OUT : out std_logic_vector(17 downto 0); + MEM_11_D_OUT : out std_logic_vector(17 downto 0); + MEM_12_D_OUT : out std_logic_vector(17 downto 0); + MEM_13_D_OUT : out std_logic_vector(17 downto 0); + MEM_14_D_OUT : out std_logic_vector(17 downto 0); + MEM_15_D_OUT : out std_logic_vector(17 downto 0); + + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of slv_ped_thr_mem is + +-- Signals + type STATES is (SLEEP, + RD_RDY, + RD_DEL0, + RD_DEL1, + WR_DEL0, + WR_DEL1, + WR_RDY, + RD_ACK, + WR_ACK, + DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + +-- statemachine signals + signal slv_ack_x : std_logic; + signal slv_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + + signal block_addr : std_logic_vector(3 downto 0); + + type ped_data_t is array (0 to 15) of std_logic_vector(17 downto 0); + signal ped_data : ped_data_t; + signal mem_data : ped_data_t; + + signal mem_wr_x : std_logic_vector(15 downto 0); + signal mem_wr : std_logic_vector(15 downto 0); + signal mem_sel : std_logic_vector(15 downto 0); + + signal rdback_data : std_logic_vector(17 downto 0); + +begin + +--------------------------------------------------------- +-- Mapping of backplanes -- +--------------------------------------------------------- + THE_APV_ADC_MAP_MEM: apv_adc_map_mem + port map ( + ADDRESS(6 downto 4) => backplane_in, + ADDRESS(3 downto 0) => slv_addr_in(10 downto 7), + Q => block_addr + ); + + THE_MEM_SEL_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + case block_addr is + when x"0" => mem_sel <= b"0000_0000_0000_0001"; + rdback_data <= mem_data(0); + when x"1" => mem_sel <= b"0000_0000_0000_0010"; + rdback_data <= mem_data(1); + when x"2" => mem_sel <= b"0000_0000_0000_0100"; + rdback_data <= mem_data(2); + when x"3" => mem_sel <= b"0000_0000_0000_1000"; + rdback_data <= mem_data(3); + when x"4" => mem_sel <= b"0000_0000_0001_0000"; + rdback_data <= mem_data(4); + when x"5" => mem_sel <= b"0000_0000_0010_0000"; + rdback_data <= mem_data(5); + when x"6" => mem_sel <= b"0000_0000_0100_0000"; + rdback_data <= mem_data(6); + when x"7" => mem_sel <= b"0000_0000_1000_0000"; + rdback_data <= mem_data(7); + when x"8" => mem_sel <= b"0000_0001_0000_0000"; + rdback_data <= mem_data(8); + when x"9" => mem_sel <= b"0000_0010_0000_0000"; + rdback_data <= mem_data(9); + when x"a" => mem_sel <= b"0000_0100_0000_0000"; + rdback_data <= mem_data(10); + when x"b" => mem_sel <= b"0000_1000_0000_0000"; + rdback_data <= mem_data(11); + when x"c" => mem_sel <= b"0001_0000_0000_0000"; + rdback_data <= mem_data(12); + when x"d" => mem_sel <= b"0010_0000_0000_0000"; + rdback_data <= mem_data(13); + when x"e" => mem_sel <= b"0100_0000_0000_0000"; + rdback_data <= mem_data(14); + when x"f" => mem_sel <= b"1000_0000_0000_0000"; + rdback_data <= mem_data(15); + when others => mem_sel <= b"0000_0000_0000_0000"; -- never used + rdback_data <= (others => '0'); + end case; + end if; + end process THE_MEM_SEL_PROC; + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process + STATE_MEM: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; + end process STATE_MEM; + +-- Transition matrix + TRANSFORM: process( CURRENT_STATE, slv_read_in, slv_write_in ) + begin + NEXT_STATE <= SLEEP; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => if ( slv_read_in = '1' ) then + NEXT_STATE <= RD_DEL0; + store_rd_x <= '1'; + elsif( slv_write_in = '1' ) then + NEXT_STATE <= WR_DEL0; + store_wr_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when RD_DEL0 => NEXT_STATE <= RD_DEL1; + when RD_DEL1 => NEXT_STATE <= RD_RDY; + when RD_RDY => NEXT_STATE <= RD_ACK; + when RD_ACK => if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + slv_ack_x <= '1'; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + when WR_DEL0 => NEXT_STATE <= WR_DEL1; + when WR_DEL1 => NEXT_STATE <= WR_RDY; + when WR_RDY => NEXT_STATE <= WR_ACK; + when WR_ACK => if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + slv_ack_x <= '1'; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + when DONE => NEXT_STATE <= SLEEP; + + when others => NEXT_STATE <= SLEEP; + end case; + end process TRANSFORM; + +--------------------------------------------------------- +-- block memories -- +--------------------------------------------------------- + GEN_PED_MEM: for i in 0 to 15 generate + -- Port A: SLV_BUS + -- Port B: state machine + THE_PED_MEM: ped_thr_true + port map( + DATAINA => slv_data_in(17 downto 0), + DATAINB => b"00_0000_0000_0000_0000", + ADDRESSA => slv_addr_in(6 downto 0), + ADDRESSB => mem_addr_in, + CLOCKA => clk_in, + CLOCKB => mem_clk_in, + CLOCKENA => '1', + CLOCKENB => '1', + WRA => mem_wr(i), -- BUGBUGBUG + WRB => '0', -- state machine never writes! + RESETA => reset_in, + RESETB => reset_in, + QA => mem_data(i), + QB => ped_data(i) + ); + -- Write signals + mem_wr_x(i) <= '1' when ( (mem_sel(i) = '1') and (store_wr = '1') ) else '0'; + end generate GEN_PED_MEM; + +-- Synchronize + THE_SYNC_PROC: process(clk_in) + begin + if( rising_edge(clk_in) ) then + mem_wr <= mem_wr_x; + end if; + end process THE_SYNC_PROC; + +--------------------------------------------------------- +-- output signals -- +--------------------------------------------------------- + slv_ack_out <= slv_ack; + slv_data_out <= b"0000_0000_0000_00" & rdback_data; + + mem_0_d_out <= ped_data(0); + mem_1_d_out <= ped_data(1); + mem_2_d_out <= ped_data(2); + mem_3_d_out <= ped_data(3); + mem_4_d_out <= ped_data(4); + mem_5_d_out <= ped_data(5); + mem_6_d_out <= ped_data(6); + mem_7_d_out <= ped_data(7); + mem_8_d_out <= ped_data(8); + mem_9_d_out <= ped_data(9); + mem_10_d_out <= ped_data(10); + mem_11_d_out <= ped_data(11); + mem_12_d_out <= ped_data(12); + mem_13_d_out <= ped_data(13); + mem_14_d_out <= ped_data(14); + mem_15_d_out <= ped_data(15); + + stat(31 downto 20) <= (others => '0'); + stat(19 downto 16) <= block_addr; + stat(15 downto 0) <= mem_sel; + +end Behavioral; diff --git a/nxyter/source/slv_register.vhd b/nxyter/source/slv_register.vhd new file mode 100644 index 0000000..81ec7e3 --- /dev/null +++ b/nxyter/source/slv_register.vhd @@ -0,0 +1,205 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library work; +use work.adcmv3_components.all; + +entity slv_register is + generic( + RESET_VALUE : std_logic_vector(31 downto 0) := x"0000_0000" + ); + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + BUSY_IN : in std_logic; + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_BUSY_OUT : out std_logic; + SLV_ACK_OUT : out std_logic; + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + -- I/O to the backend + REG_DATA_IN : in std_logic_vector(31 downto 0); + REG_DATA_OUT : out std_logic_vector(31 downto 0); + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of slv_register is + +-- Signals + type STATES is (SLEEP, + RD_BSY, + WR_BSY, + RD_RDY, + WR_RDY, + RD_ACK, + WR_ACK, + DONE + ); + signal CURRENT_STATE, NEXT_STATE: STATES; + +-- slave bus signals + signal slv_busy_x : std_logic; + signal slv_busy : std_logic; + signal slv_ack_x : std_logic; + signal slv_ack : std_logic; + signal store_wr_x : std_logic; + signal store_wr : std_logic; + signal store_rd_x : std_logic; + signal store_rd : std_logic; + + signal reg_slv_data_in : std_logic_vector(31 downto 0); -- registered data input + signal reg_slv_data_out : std_logic_vector(31 downto 0); -- read back data + signal reg_busy : std_logic; + +begin + +-- Fake + reg_busy <= busy_in; + stat <= (others => '0'); + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +-- State memory process + PROC_STATE_MEM: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + slv_busy <= '0'; + slv_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + slv_busy <= slv_busy_x; + slv_ack <= slv_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; + end process PROC_STATE_MEM; + +-- Transition matrix + PROC_TRANSFORM: process(CURRENT_STATE, slv_read_in, slv_write_in, reg_busy) + begin + NEXT_STATE <= SLEEP; + slv_busy_x <= '0'; + slv_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + + case CURRENT_STATE is + + when SLEEP => + if ( (reg_busy = '0') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (reg_busy = '0') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + elsif( (reg_busy = '1') and (slv_read_in = '1') ) then + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + elsif( (reg_busy = '1') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + + when RD_RDY => + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + + when WR_RDY => + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + + when RD_ACK => + if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_ACK; + slv_ack_x <= '1'; + end if; + + when WR_ACK => + if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_ACK; + slv_ack_x <= '1'; + end if; + + when RD_BSY => + if( slv_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_BSY; + slv_busy_x <= '1'; + end if; + + when WR_BSY => + if( slv_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; + end if; + + when DONE => + NEXT_STATE <= SLEEP; + + when others => + NEXT_STATE <= SLEEP; + + end case; + end process PROC_TRANSFORM; + +--------------------------------------------------------- +-- data handling -- +--------------------------------------------------------- + +-- register write + PROC_WRITE_REG: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_in <= RESET_VALUE; + elsif( store_wr = '1' ) then + reg_slv_data_in <= slv_data_in; + end if; + end if; + end process PROC_WRITE_REG; + +-- register read + PROC_READ_REG: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_slv_data_out <= (others => '0'); + elsif( store_rd = '1' ) then + reg_slv_data_out <= reg_data_in; + end if; + end if; + end process PROC_READ_REG; + +-- output signals + slv_ack_out <= slv_ack; + slv_busy_out <= slv_busy; + slv_data_out <= reg_slv_data_out; + +--------------------------------------------------------- +-- signals to backend -- +--------------------------------------------------------- + + reg_data_out <= reg_slv_data_in; + +end Behavioral; -- 2.43.0