From 27d0127f5fe65746c2896ea0f4bb29d4c464ca5c Mon Sep 17 00:00:00 2001 From: Ludwig Maier Date: Mon, 5 Aug 2013 03:10:02 +0200 Subject: [PATCH] adc working, i2c clock stretching... --- nxyter/source/debug_multiplexer.vhd | 111 +++++ nxyter/source/nx_data_receiver.vhd | 23 +- nxyter/source/nx_data_validate.vhd | 2 +- nxyter/source/nx_event_buffer.vhd | 177 ++++---- nxyter/source/nx_histograms.vhd | 90 +++- nxyter/source/nx_i2c_master.vhd | 206 +++++---- nxyter/source/nx_i2c_readbyte.vhd | 29 +- nxyter/source/nx_i2c_sendbyte.vhd | 170 ++++--- nxyter/source/nx_setup.vhd | 595 +++++++++++++++---------- nxyter/source/nx_trigger_generator.vhd | 31 +- nxyter/source/nx_trigger_handler.vhd | 200 +++++---- nxyter/source/nx_trigger_validate.vhd | 122 +++-- nxyter/source/nxyter_components.vhd | 30 +- nxyter/source/nxyter_fee_board.vhd | 118 +++-- nxyter/source/registers.txt | 35 +- nxyter/trb3_periph.prj | 1 + nxyter/trb3_periph_constraints.lpf | 4 +- 17 files changed, 1235 insertions(+), 709 deletions(-) create mode 100644 nxyter/source/debug_multiplexer.vhd diff --git a/nxyter/source/debug_multiplexer.vhd b/nxyter/source/debug_multiplexer.vhd new file mode 100644 index 0000000..ac02bf3 --- /dev/null +++ b/nxyter/source/debug_multiplexer.vhd @@ -0,0 +1,111 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.nxyter_components.all; + +entity debug_multiplexer is + generic ( + NUM_PORTS : integer range 1 to 32 := 1 + ); + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + DEBUG_LINE_IN : in debug_array_t(0 to NUM_PORTS-1); + DEBUG_LINE_OUT : out std_logic_vector(15 downto 0); + + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic + + ); +end entity; + +architecture Behavioral of debug_multiplexer is + + signal port_select : std_logic_vector(7 downto 0); + signal debug_line_o : std_logic_vector(15 downto 0); + + signal slv_data_out_o : std_logic_vector(31 downto 0); + signal slv_no_more_data_o : std_logic; + signal slv_unknown_addr_o : std_logic; + signal slv_ack_o : std_logic; + +begin + + PROC_MULTIPLEXER: process(port_select, + DEBUG_LINE_IN) + begin + if (unsigned(port_select) < NUM_PORTS) then + debug_line_o <= DEBUG_LINE_IN(to_integer(unsigned(port_select))); + else + debug_line_o <= (others => '1'); + end if; + end process PROC_MULTIPLEXER; + + PROC_SLAVE_BUS: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + port_select <= (others => '0'); + else + slv_ack_o <= '1'; + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + + if (SLV_WRITE_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + if (unsigned(SLV_DATA_IN(7 downto 0)) < NUM_PORTS) then + port_select <= SLV_DATA_IN(7 downto 0); + end if; + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; + end case; + + elsif (SLV_READ_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + slv_data_out_o(7 downto 0) <= port_select; + slv_data_out_o(31 downto 8) <= (others => '0'); + + when others => + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; + end case; + + else + slv_ack_o <= '0'; + end if; + end if; + end if; + end process PROC_SLAVE_BUS; + + ----------------------------------------------------------------------------- + -- Output Signals + ----------------------------------------------------------------------------- + + SLV_DATA_OUT <= slv_data_out_o; + SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; + SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; + SLV_ACK_OUT <= slv_ack_o; + + DEBUG_LINE_OUT <= debug_line_o; + +end Behavioral; diff --git a/nxyter/source/nx_data_receiver.vhd b/nxyter/source/nx_data_receiver.vhd index df58379..b344212 100644 --- a/nxyter/source/nx_data_receiver.vhd +++ b/nxyter/source/nx_data_receiver.vhd @@ -133,6 +133,7 @@ architecture Behavioral of nx_data_receiver is signal adc_reset : std_logic; signal adc_data : std_logic_vector(11 downto 0); + signal test_adc_data : std_logic_vector(11 downto 0); signal adc_data_valid : std_logic; signal adc_data_t : std_logic_vector(11 downto 0); @@ -167,14 +168,15 @@ begin DEBUG_OUT(0) <= CLK_IN; DEBUG_OUT(2 downto 1) <= STATE_d; - DEBUG_OUT(3) <= nx_new_timestamp; - DEBUG_OUT(4) <= adc_new_data; - DEBUG_OUT(5) <= new_data_o; - DEBUG_OUT(6) <= nx_fifo_data_valid; - DEBUG_OUT(7) <= valid_data_d;--(others => '0'); - DEBUG_OUT(15 downto 8) <= nx_timestamp_reg; + DEBUG_OUT(3) <= adc_data_valid; -- nx_new_timestamp; + --DEBUG_OUT(4) <= adc_new_data; + --DEBUG_OUT(5) <= new_data_o; + --DEBUG_OUT(6) <= nx_fifo_data_valid; + --DEBUG_OUT(7) <= valid_data_d;--(others => '0'); + --DEBUG_OUT(15 downto 8) <= nx_timestamp_reg; --DEBUG_OUT(15 downto 8) <= (others => '0'); - + DEBUG_OUT(15 downto 4) <= test_adc_data; + PROC_DEBUG: process(NX_TIMESTAMP_CLK_IN) begin if( rising_edge(NX_TIMESTAMP_CLK_IN) ) then @@ -209,8 +211,8 @@ begin ADCCLK_OUT => ADC_SAMPLE_CLK_OUT, ADC_DATA(0) => ADC_NX_IN(0), - ADC_DATA(1) => ADC_A_IN(0), - ADC_DATA(2) => ADC_B_IN(0), + ADC_DATA(1) => ADC_B_IN(0), + ADC_DATA(2) => ADC_A_IN(0), ADC_DATA(3) => ADC_D_IN(0), ADC_DATA(4) => ADC_NX_IN(1), @@ -222,7 +224,8 @@ begin ADC_FCO => ADC_FCLK_IN, DATA_OUT(11 downto 0) => adc_data, - DATA_OUT(95 downto 12) => open, + DATA_OUT(23 downto 12) => test_adc_data, + DATA_OUT(95 downto 24) => open, FCO_OUT => open, DATA_VALID_OUT(0) => adc_data_valid, diff --git a/nxyter/source/nx_data_validate.vhd b/nxyter/source/nx_data_validate.vhd index 1bc8d71..9c52243 100644 --- a/nxyter/source/nx_data_validate.vhd +++ b/nxyter/source/nx_data_validate.vhd @@ -202,7 +202,7 @@ begin if (new_timestamp = '1') then case valid_frame_bits is - + -- Data Frame when "1000" => ---- Check Overflow diff --git a/nxyter/source/nx_event_buffer.vhd b/nxyter/source/nx_event_buffer.vhd index 8abae5e..69ed4cb 100644 --- a/nxyter/source/nx_event_buffer.vhd +++ b/nxyter/source/nx_event_buffer.vhd @@ -72,7 +72,8 @@ architecture Behavioral of nx_event_buffer is signal fifo_write_enable : std_logic; -- NOMORE_DATA RS FlipFlop - signal flush_end : std_logic; + signal flush_end_enable_set : std_logic; + signal flush_end_enable : std_logic; -- FIFO Read Handler signal fifo_o : std_logic_vector(31 downto 0); @@ -95,17 +96,16 @@ architecture Behavioral of nx_event_buffer is signal R_STATE : R_STATES; -- Event Buffer Output Handler - signal evt_data_clk : std_logic; - signal evt_data_flushed : std_logic; - - signal fifo_read_enable_f : std_logic; - signal fifo_read_enable_f2 : std_logic; - signal fifo_flush_ctr : unsigned(10 downto 0); - - signal evt_data_flushed_x : std_logic; - signal fifo_flush_ctr_x : unsigned(10 downto 0); - signal flush_end_reset : std_logic; - signal flush_end_reset_x : std_logic; + signal evt_data_clk : std_logic; + signal evt_data_flushed : std_logic; + + signal fifo_read_enable_f : std_logic; + signal fifo_read_enable_f2 : std_logic; + signal fifo_flush_ctr : unsigned(10 downto 0); + + signal evt_data_flushed_x : std_logic; + signal fifo_flush_ctr_x : unsigned(10 downto 0); + signal flush_end_enable_reset_x : std_logic; type F_STATES is (F_IDLE, F_FLUSH, @@ -124,12 +124,10 @@ architecture Behavioral of nx_event_buffer is signal data_wait : std_logic; - signal evt_data_flush_r : std_logic; - begin DEBUG_OUT(0) <= CLK_IN; - --DEBUG_OUT(1) <= evt_data_flush_r; + DEBUG_OUT(1) <= '0'; DEBUG_OUT(2) <= evt_data_clk; DEBUG_OUT(3) <= fifo_empty; DEBUG_OUT(4) <= fifo_read_enable; @@ -139,7 +137,9 @@ begin --DEBUG_OUT(15 downto 8) <= evt_data_o(31 downto 24); DEBUG_OUT(8) <= LVL2_TRIGGER_IN; - DEBUG_OUT(11 downto 9) <= (others => '0'); + DEBUG_OUT(9) <= evt_data_flushed; + DEBUG_OUT(10) <= FAST_CLEAR_IN; + DEBUG_OUT(12) <= flush_end_enable; DEBUG_OUT(13) <= fee_data_write_o; DEBUG_OUT(14) <= fee_data_finished_o; DEBUG_OUT(15) <= FEE_DATA_ALMOST_FULL_IN; @@ -152,39 +152,47 @@ begin begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then + evt_data_flush <= '0'; fee_data_finished_o <= '0'; trigger_busy_o <= '0'; STATE <= S_IDLE; else + evt_data_flush <= '0'; fee_data_finished_o <= '0'; trigger_busy_o <= '1'; - - case STATE is - when S_IDLE => - if (NXYTER_OFFLINE_IN = '1') then - fee_data_finished_o <= '1'; - trigger_busy_o <= '0'; - STATE <= S_IDLE; - elsif (LVL2_TRIGGER_IN = '1') then - evt_data_flush <= '1'; - STATE <= S_FLUSH_BUFFER_WAIT; - else - trigger_busy_o <= '0'; - STATE <= S_IDLE; - end if; - - when S_FLUSH_BUFFER_WAIT => - if (evt_data_flushed = '0') then - STATE <= S_FLUSH_BUFFER_WAIT; - else - fee_data_finished_o <= '1'; - STATE <= S_IDLE; - end if; - - end case; + DEBUG_OUT(11) <= '0'; + + if (FAST_CLEAR_IN = '1') then + fee_data_finished_o <= '1'; + STATE <= S_IDLE; + else + case STATE is + when S_IDLE => + if (NXYTER_OFFLINE_IN = '1') then + fee_data_finished_o <= '1'; + trigger_busy_o <= '0'; + STATE <= S_IDLE; + elsif (LVL2_TRIGGER_IN = '1') then + evt_data_flush <= '1'; + STATE <= S_FLUSH_BUFFER_WAIT; + else + trigger_busy_o <= '0'; + STATE <= S_IDLE; + end if; + + when S_FLUSH_BUFFER_WAIT => + DEBUG_OUT(11) <= '1'; + if (evt_data_flushed = '0') then + STATE <= S_FLUSH_BUFFER_WAIT; + else + fee_data_finished_o <= '1'; + STATE <= S_IDLE; + end if; + + end case; + end if; end if; end if; - end process PROC_DATA_HANDLER; ----------------------------------------------------------------------------- @@ -226,37 +234,37 @@ begin end if; end process PROC_FIFO_WRITE_HANDLER; - PROC_FLUSH_END_RS: process(CLK_IN) + PROC_FLUSH_END_RS_FF: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then - if( RESET_IN = '1' or flush_end_reset = '1') then - flush_end <= '0'; + if( RESET_IN = '1' or flush_end_enable_reset_x = '1') then + flush_end_enable <= '0'; else - if (EVT_NOMORE_DATA_IN = '1') then - flush_end <= '1'; + if (flush_end_enable_set = '1') then + flush_end_enable <= '1'; end if; end if; end if; - end process PROC_FLUSH_END_RS; - + end process PROC_FLUSH_END_RS_FF; + + flush_end_enable_set <= EVT_NOMORE_DATA_IN; + PROC_FLUSH_BUFFER_TRANSFER: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - evt_data_clk <= '0'; - evt_data_flushed <= '0'; - fifo_flush_ctr <= (others => '0'); - fifo_read_enable_f2 <= '0'; - flush_end_reset <= '0'; - F_STATE <= F_IDLE; + evt_data_clk <= '0'; + evt_data_flushed <= '0'; + fifo_flush_ctr <= (others => '0'); + fifo_read_enable_f2 <= '0'; + F_STATE <= F_IDLE; else - evt_data_flushed <= evt_data_flushed_x; - fifo_flush_ctr <= fifo_flush_ctr_x; - flush_end_reset <= flush_end_reset_x; - F_STATE <= F_NEXT_STATE; + evt_data_flushed <= evt_data_flushed_x; + fifo_flush_ctr <= fifo_flush_ctr_x; + F_STATE <= F_NEXT_STATE; - fifo_read_enable_f2 <= fifo_read_enable_f; - evt_data_clk <= fifo_read_enable_f2; + fifo_read_enable_f2 <= fifo_read_enable_f; + evt_data_clk <= fifo_read_enable_f2; end if; end if; end process PROC_FLUSH_BUFFER_TRANSFER; @@ -265,51 +273,51 @@ begin evt_data_flush, fifo_empty, evt_data_clk, - flush_end + flush_end_enable ) begin -- Defaults - fifo_read_enable_f <= '0'; - fifo_flush_ctr_x <= fifo_flush_ctr; - evt_data_flushed_x <= '0'; - flush_end_reset_x <= '0'; + fifo_read_enable_f <= '0'; + fifo_flush_ctr_x <= fifo_flush_ctr; + evt_data_flushed_x <= '0'; + flush_end_enable_reset_x <= '0'; -- Multiplexer fee_data_o if (evt_data_clk = '1') then - fee_data_o <= fifo_o; - fee_data_write_o <= '1'; + fee_data_o <= fifo_o; + fee_data_write_o <= '1'; else - fee_data_o <= (others => '1'); - fee_data_write_o <= '0'; + fee_data_o <= (others => '1'); + fee_data_write_o <= '0'; end if; -- FIFO Read Handler case F_STATE is when F_IDLE => if (evt_data_flush = '1') then - fifo_flush_ctr_x <= (others => '0'); - flush_end_reset_x <= '1'; - F_NEXT_STATE <= F_FLUSH; + fifo_flush_ctr_x <= (others => '0'); + flush_end_enable_reset_x <= '1'; + F_NEXT_STATE <= F_FLUSH; else - F_NEXT_STATE <= F_IDLE; + F_NEXT_STATE <= F_IDLE; end if; when F_FLUSH => if (fifo_empty = '0') then - fifo_read_enable_f <= '1'; - fifo_flush_ctr_x <= fifo_flush_ctr + 1; - F_NEXT_STATE <= F_FLUSH; + fifo_read_enable_f <= '1'; + fifo_flush_ctr_x <= fifo_flush_ctr + 1; + F_NEXT_STATE <= F_FLUSH; else - if (flush_end = '0') then - F_NEXT_STATE <= F_FLUSH; + if (flush_end_enable = '0') then + F_NEXT_STATE <= F_FLUSH; else - F_NEXT_STATE <= F_END; + F_NEXT_STATE <= F_END; end if; end if; when F_END => - evt_data_flushed_x <= '1'; - F_NEXT_STATE <= F_IDLE; + evt_data_flushed_x <= '1'; + F_NEXT_STATE <= F_IDLE; end case; end process PROC_FLUSH_BUFFER; @@ -394,7 +402,6 @@ begin fifo_read_start <= '0'; data_wait <= '0'; - evt_data_flush_r <= '0'; else slv_data_out_o <= (others => '0'); slv_ack_o <= '0'; @@ -403,7 +410,6 @@ begin fifo_read_start <= '0'; data_wait <= '0'; - evt_data_flush_r <= '0'; if (data_wait = '1') then if (fifo_read_done = '0') then @@ -445,11 +451,6 @@ begin elsif (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is - - when x"0000" => - evt_data_flush_r <= '1'; - slv_ack_o <= '1'; - when others => slv_unknown_addr_o <= '1'; slv_ack_o <= '0'; diff --git a/nxyter/source/nx_histograms.vhd b/nxyter/source/nx_histograms.vhd index e998cb1..d7b83dc 100644 --- a/nxyter/source/nx_histograms.vhd +++ b/nxyter/source/nx_histograms.vhd @@ -2,9 +2,13 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +library work; +use work.nxyter_components.all; + entity nx_histograms is generic ( - NUM_BINS : integer := 7 + BUS_WIDTH : integer := 7; + ENABLE : integer := 1 ); port ( CLK_IN : in std_logic; @@ -13,7 +17,7 @@ entity nx_histograms is RESET_HISTS_IN : in std_logic; CHANNEL_STAT_FILL_IN : in std_logic; - CHANNEL_ID_IN : in std_logic_vector(NUM_BINS - 1 downto 0); + CHANNEL_ID_IN : in std_logic_vector(BUS_WIDTH - 1 downto 0); -- Slave bus SLV_READ_IN : in std_logic; @@ -32,8 +36,13 @@ end entity; architecture nx_histograms of nx_histograms is - type histogram_t is array(0 to 127) of unsigned(31 downto 0); + type histogram_t is array(0 to 2**BUS_WIDTH - 1) of unsigned(23 downto 0); + + -- PROC_CHANNEL_HIST signal hist_channel_stat : histogram_t; + signal hist_channel_freq : histogram_t; + signal wait_timer_init : unsigned(27 downto 0); + signal wait_timer_done : std_logic; -- Slave Bus signal slv_data_out_o : std_logic_vector(31 downto 0); @@ -43,28 +52,65 @@ architecture nx_histograms of nx_histograms is signal reset_hists_r : std_logic; begin + +hist_enable_1: if ENABLE = 1 generate + DEBUG_OUT(0) <= CLK_IN; + DEBUG_OUT(1) <= RESET_IN; + DEBUG_OUT(2) <= RESET_HISTS_IN; + DEBUG_OUT(3) <= reset_hists_r; + DEBUG_OUT(4) <= slv_ack_o; + DEBUG_OUT(5) <= SLV_READ_IN; + DEBUG_OUT(6) <= SLV_WRITE_IN; + DEBUG_OUT(7) <= wait_timer_done; + DEBUG_OUT(15 downto 8) <= (others => '0'); + + ----------------------------------------------------------------------------- PROC_CHANNEL_HIST : process (CLK_IN) begin if( rising_edge(CLK_IN) ) then if (RESET_IN = '1' or reset_hists_r = '1' or RESET_HISTS_IN = '1') then - for I in (NUM_BINS - 1) downto 0 loop + for I in 0 to (2**BUS_WIDTH - 1) loop hist_channel_stat(I) <= (others => '0'); + hist_channel_freq(I) <= (others => '0'); end loop; + wait_timer_init <= x"000_0001"; else - if (CHANNEL_STAT_FILL_IN = '1') then - hist_channel_stat(to_integer(unsigned(CHANNEL_ID_IN))) <= - hist_channel_stat(to_integer(unsigned(CHANNEL_ID_IN))) + 1; + wait_timer_init <= (others => '0'); + if (wait_timer_done = '1') then + for I in 0 to (2**BUS_WIDTH - 1) loop + hist_channel_stat(I) <= (others => '0'); + hist_channel_freq(I) <= + (hist_channel_freq(I) + hist_channel_stat(I)) / 2; + end loop; + wait_timer_init <= x"5f5_e100"; + else + if (CHANNEL_STAT_FILL_IN = '1') then + hist_channel_stat(to_integer(unsigned(CHANNEL_ID_IN))) <= + hist_channel_stat(to_integer(unsigned(CHANNEL_ID_IN))) + 1; + end if; end if; end if; end if; end process PROC_CHANNEL_HIST; + -- Timer + nx_timer_1: nx_timer + generic map ( + CTR_WIDTH => 28 + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + TIMER_START_IN => wait_timer_init, + TIMER_DONE_OUT => wait_timer_done + ); ----------------------------------------------------------------------------- -- TRBNet Slave Bus ----------------------------------------------------------------------------- - -- Give status info to the TRB Slow Control Channel + + -- Give status info to the TRB Slow Control Channel PROC_HISTOGRAMS_READ: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then @@ -78,21 +124,28 @@ begin slv_data_out_o <= (others => '0'); slv_unknown_addr_o <= '0'; slv_no_more_data_o <= '0'; - slv_ack_o <= '0'; reset_hists_r <= '0'; if (SLV_READ_IN = '1') then if (unsigned(SLV_ADDR_IN) >= x"0000" and - unsigned(SLV_ADDR_IN) < x"0080") then - slv_data_out_o <= std_logic_vector( + unsigned(SLV_ADDR_IN) <= x"007f") then + slv_data_out_o(23 downto 0) <= std_logic_vector( hist_channel_stat(to_integer(unsigned(SLV_ADDR_IN(7 downto 0)))) ); - slv_ack_o <= '1'; + slv_data_out_o(31 downto 24) <= (others => '0'); + slv_ack_o <= '1'; + elsif (unsigned(SLV_ADDR_IN) >= x"0080" and + unsigned(SLV_ADDR_IN) <= x"00ff") then + slv_data_out_o(23 downto 0) <= std_logic_vector( + hist_channel_freq(to_integer(unsigned(SLV_ADDR_IN(7 downto 0)))) + ); + slv_data_out_o(31 downto 24) <= (others => '0'); + slv_ack_o <= '1'; else - slv_unknown_addr_o <= '1'; - end if; - + slv_ack_o <= '0'; + end if; + elsif (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is @@ -103,13 +156,16 @@ begin when others => slv_unknown_addr_o <= '1'; - + slv_ack_o <= '0'; end case; + else + slv_ack_o <= '0'; end if; end if; end if; end process PROC_HISTOGRAMS_READ; - + +end generate hist_enable_1; ----------------------------------------------------------------------------- -- Output Signals ----------------------------------------------------------------------------- diff --git a/nxyter/source/nx_i2c_master.vhd b/nxyter/source/nx_i2c_master.vhd index 2ac23de..e0a9d18 100644 --- a/nxyter/source/nx_i2c_master.vhd +++ b/nxyter/source/nx_i2c_master.vhd @@ -39,6 +39,9 @@ end entity; architecture Behavioral of nx_i2c_master is + signal sda_o : std_logic; + signal scl_o : std_logic; + signal sda_i : std_logic; signal sda_x : std_logic; signal sda : std_logic; @@ -49,10 +52,9 @@ architecture Behavioral of nx_i2c_master is signal command_busy_o : std_logic; -- I2C Master - signal sda_o : std_logic; - signal scl_o : std_logic; + signal sda_master : std_logic; + signal scl_master : std_logic; signal i2c_start : std_logic; - signal i2c_busy : std_logic; signal startstop_select : std_logic; signal startstop_seq_start : std_logic; @@ -128,11 +130,14 @@ begin -- Debug DEBUG_OUT(0) <= CLK_IN; DEBUG_OUT(8 downto 1) <= i2c_data(7 downto 0); - DEBUG_OUT(12 downto 9) <= i2c_data(31 downto 28); - DEBUG_OUT(13) <= i2c_busy; - DEBUG_OUT(14) <= internal_command; - DEBUG_OUT(15) <= internal_command_d; - + DEBUG_OUT(10 downto 9) <= i2c_data(31 downto 30); + DEBUG_OUT(11) <= i2c_busy; + DEBUG_OUT(12) <= sda_o; + DEBUG_OUT(13) <= scl_o; + DEBUG_OUT(14) <= sda; + DEBUG_OUT(15) <= scl; + --DEBUG_OUT(12 downto 9) <= i2c_data(31 downto 28); + -- Start / Stop Sequence nx_i2c_startstop_1: nx_i2c_startstop generic map ( @@ -162,6 +167,7 @@ begin SDA_OUT => sda_sendbyte, SCL_OUT => scl_sendbyte, SDA_IN => sda, + SCL_IN => scl, ACK_OUT => sendbyte_ack ); @@ -243,150 +249,152 @@ begin begin -- Defaults - sda_o <= '1'; - scl_o <= '1'; - i2c_busy_x <= '1'; - startstop_select_x <= '0'; - startstop_seq_start_x <= '0'; - sendbyte_seq_start_x <= '0'; - sendbyte_byte_x <= (others => '0'); - readbyte_seq_start_x <= '0'; - i2c_data_x <= i2c_data; - read_seq_ctr_x <= read_seq_ctr; + sda_master <= '1'; + scl_master <= '1'; + i2c_busy_x <= '1'; + startstop_select_x <= '0'; + startstop_seq_start_x <= '0'; + sendbyte_seq_start_x <= '0'; + sendbyte_byte_x <= (others => '0'); + readbyte_seq_start_x <= '0'; + i2c_data_x <= i2c_data; + read_seq_ctr_x <= read_seq_ctr; case STATE is when S_RESET => - i2c_data_x <= (others => '0'); - NEXT_STATE <= S_IDLE; + i2c_data_x <= (others => '0'); + NEXT_STATE <= S_IDLE; when S_IDLE => if (i2c_start = '1') then - i2c_data_x <= x"8000_0000"; -- Set Running, clear all other bits - NEXT_STATE <= S_START; + i2c_data_x <= x"8000_0000"; -- Set Running, clear all + -- other bits + NEXT_STATE <= S_START; else - i2c_busy_x <= '0'; - i2c_data_x <= i2c_data and x"7fff_ffff"; -- clear running bit; - read_seq_ctr_x <= '0'; - NEXT_STATE <= S_IDLE; + i2c_busy_x <= '0'; + i2c_data_x <= i2c_data and x"7fff_ffff"; -- clear running + -- bit; + read_seq_ctr_x <= '0'; + NEXT_STATE <= S_IDLE; end if; -- I2C START Sequence when S_START => - startstop_select_x <= '1'; - startstop_seq_start_x <= '1'; - NEXT_STATE <= S_START_WAIT; + startstop_select_x <= '1'; + startstop_seq_start_x <= '1'; + NEXT_STATE <= S_START_WAIT; when S_START_WAIT => if (startstop_done = '0') then - NEXT_STATE <= S_START_WAIT; + NEXT_STATE <= S_START_WAIT; else - sda_o <= '0'; - scl_o <= '0'; - NEXT_STATE <= S_SEND_CHIP_ID; + sda_master <= '0'; + scl_master <= '0'; + NEXT_STATE <= S_SEND_CHIP_ID; end if; -- I2C SEND ChipId Sequence when S_SEND_CHIP_ID => - scl_o <= '0'; + scl_master <= '0'; sendbyte_byte_x(7 downto 1) <= i2c_chipid; if (read_seq_ctr = '0') then - sendbyte_byte_x(0) <= '0'; + sendbyte_byte_x(0) <= '0'; else - sendbyte_byte_x(0) <= '1'; + sendbyte_byte_x(0) <= '1'; end if; - sendbyte_seq_start_x <= '1'; - NEXT_STATE <= S_SEND_CHIP_ID_WAIT; + sendbyte_seq_start_x <= '1'; + NEXT_STATE <= S_SEND_CHIP_ID_WAIT; when S_SEND_CHIP_ID_WAIT => if (sendbyte_done = '0') then - NEXT_STATE <= S_SEND_CHIP_ID_WAIT; + NEXT_STATE <= S_SEND_CHIP_ID_WAIT; else - scl_o <= '0'; + scl_master <= '0'; if (sendbyte_ack = '0') then - i2c_data_x <= i2c_data or x"0100_0000"; - NEXT_STATE <= S_STOP; + i2c_data_x <= i2c_data or x"0100_0000"; + NEXT_STATE <= S_STOP; else if (read_seq_ctr = '0') then - read_seq_ctr_x <= '1'; - NEXT_STATE <= S_SEND_REGISTER; + read_seq_ctr_x <= '1'; + NEXT_STATE <= S_SEND_REGISTER; else - NEXT_STATE <= S_GET_DATA; + NEXT_STATE <= S_GET_DATA; end if; end if; end if; -- I2C SEND RegisterId when S_SEND_REGISTER => - scl_o <= '0'; - sendbyte_byte_x <= i2c_registerid; - sendbyte_seq_start_x <= '1'; - NEXT_STATE <= S_SEND_REGISTER_WAIT; + scl_master <= '0'; + sendbyte_byte_x <= i2c_registerid; + sendbyte_seq_start_x <= '1'; + NEXT_STATE <= S_SEND_REGISTER_WAIT; when S_SEND_REGISTER_WAIT => if (sendbyte_done = '0') then - NEXT_STATE <= S_SEND_REGISTER_WAIT; + NEXT_STATE <= S_SEND_REGISTER_WAIT; else - scl_o <= '0'; + scl_master <= '0'; if (sendbyte_ack = '0') then - i2c_data_x <= i2c_data or x"0200_0000"; - NEXT_STATE <= S_STOP; + i2c_data_x <= i2c_data or x"0200_0000"; + NEXT_STATE <= S_STOP; else if (i2c_rw_bit = '0') then - NEXT_STATE <= S_SEND_DATA; + NEXT_STATE <= S_SEND_DATA; else - NEXT_STATE <= S_START; + NEXT_STATE <= S_START; end if; end if; end if; -- I2C SEND DataWord when S_SEND_DATA => - scl_o <= '0'; - sendbyte_byte_x <= i2c_register_data; - sendbyte_seq_start_x <= '1'; - NEXT_STATE <= S_SEND_DATA_WAIT; + scl_master <= '0'; + sendbyte_byte_x <= i2c_register_data; + sendbyte_seq_start_x <= '1'; + NEXT_STATE <= S_SEND_DATA_WAIT; when S_SEND_DATA_WAIT => if (sendbyte_done = '0') then - NEXT_STATE <= S_SEND_DATA_WAIT; + NEXT_STATE <= S_SEND_DATA_WAIT; else - scl_o <= '0'; + scl_master <= '0'; if (sendbyte_ack = '0') then - i2c_data_x <= i2c_data or x"0400_0000"; + i2c_data_x <= i2c_data or x"0400_0000"; end if; - NEXT_STATE <= S_STOP; + NEXT_STATE <= S_STOP; end if; -- I2C GET DataWord when S_GET_DATA => - scl_o <= '0'; - readbyte_seq_start_x <= '1'; - NEXT_STATE <= S_GET_DATA_WAIT; + scl_master <= '0'; + readbyte_seq_start_x <= '1'; + NEXT_STATE <= S_GET_DATA_WAIT; when S_GET_DATA_WAIT => if (readbyte_done = '0') then - NEXT_STATE <= S_GET_DATA_WAIT; + NEXT_STATE <= S_GET_DATA_WAIT; else - scl_o <= '0'; - i2c_data_x(7 downto 0) <= readbyte_byte; - NEXT_STATE <= S_STOP; + scl_master <= '0'; + i2c_data_x(7 downto 0)<= readbyte_byte; + NEXT_STATE <= S_STOP; end if; -- I2C STOP Sequence when S_STOP => - sda_o <= '0'; - scl_o <= '0'; - startstop_select_x <= '0'; - startstop_seq_start_x <= '1'; - NEXT_STATE <= S_STOP_WAIT; + sda_master <= '0'; + scl_master <= '0'; + startstop_select_x <= '0'; + startstop_seq_start_x <= '1'; + NEXT_STATE <= S_STOP_WAIT; when S_STOP_WAIT => if (startstop_done = '0') then - NEXT_STATE <= S_STOP_WAIT; + NEXT_STATE <= S_STOP_WAIT; else - i2c_data_x <= i2c_data or x"4000_0000"; -- Set DONE Bit - NEXT_STATE <= S_IDLE; + i2c_data_x <= i2c_data or x"4000_0000"; -- Set DONE Bit + NEXT_STATE <= S_IDLE; end if; end case; @@ -396,17 +404,17 @@ begin begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - i2c_data_internal_o <= (others => '0'); - i2c_data_slave <= (others => '0'); - command_busy_o <= '0'; + i2c_data_internal_o <= (others => '0'); + i2c_data_slave <= (others => '0'); + command_busy_o <= '0'; else if (internal_command = '0' and internal_command_d = '0') then - i2c_data_slave <= i2c_data; + i2c_data_slave <= i2c_data; else - i2c_data_internal_o <= i2c_data; + i2c_data_internal_o <= i2c_data; end if; end if; - command_busy_o <= i2c_busy; + command_busy_o <= i2c_busy; end if; end process PROC_I2C_DATA_MULTIPLEXER; @@ -524,20 +532,22 @@ begin ----------------------------------------------------------------------------- -- I2C Outputs - SDA_INOUT <= '0' when (sda_o = '0' or - sda_startstop = '0' or - sda_sendbyte = '0' or - sda_readbyte = '0') - else 'Z'; - - SCL_INOUT <= '0' when (scl_o = '0' or - scl_startstop = '0' or - scl_sendbyte = '0' or - scl_readbyte = '0') - else 'Z'; - - COMMAND_BUSY_OUT <= command_busy_o; - I2C_DATA_OUT <= i2c_data_internal_o; + sda_o <= (sda_master and + sda_startstop and + sda_sendbyte and + sda_readbyte + ); + SDA_INOUT <= '0' when (sda_o = '0') else 'Z'; + + scl_o <= (scl_master and + scl_startstop and + scl_sendbyte and + scl_readbyte + ); + SCL_INOUT <= '0' when (scl_o = '0') else 'Z'; + + COMMAND_BUSY_OUT <= command_busy_o; + I2C_DATA_OUT <= i2c_data_internal_o; -- Slave Bus SLV_DATA_OUT <= slv_data_out_o; diff --git a/nxyter/source/nx_i2c_readbyte.vhd b/nxyter/source/nx_i2c_readbyte.vhd index 239aea6..4a9d9ab 100644 --- a/nxyter/source/nx_i2c_readbyte.vhd +++ b/nxyter/source/nx_i2c_readbyte.vhd @@ -56,9 +56,9 @@ architecture Behavioral of nx_i2c_readbyte is S_UNSET_SCL2, S_NEXT_BIT, - S_SET_ACK, - S_ACK_SET_SCL, - S_ACK_UNSET_SCL + S_NACK_SET, + S_NACK_SET_SCL, + S_NACK_UNSET_SCL ); signal STATE, NEXT_STATE : STATES; @@ -194,34 +194,31 @@ begin NEXT_STATE <= S_UNSET_SCL1; else wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_SET_ACK; + NEXT_STATE <= S_NACK_SET; end if; - -- I2C Send ACK Sequence (doesn't work, so just send a clock) - when S_SET_ACK => - --sda_o <= '0'; + -- I2C Send NOT_ACK (NACK) Sequence to tell client to release the bus + when S_NACK_SET => scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_SET_ACK; + NEXT_STATE <= S_NACK_SET; else wait_timer_init_x <= I2C_SPEED srl 1; - NEXT_STATE <= S_ACK_SET_SCL; + NEXT_STATE <= S_NACK_SET_SCL; end if; - when S_ACK_SET_SCL => - -- sda_o <= '0'; + when S_NACK_SET_SCL => if (wait_timer_done = '0') then - NEXT_STATE <= S_ACK_SET_SCL; + NEXT_STATE <= S_NACK_SET_SCL; else wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_ACK_UNSET_SCL; + NEXT_STATE <= S_NACK_UNSET_SCL; end if; - when S_ACK_UNSET_SCL => - --sda_o <= '0'; + when S_NACK_UNSET_SCL => scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_ACK_UNSET_SCL; + NEXT_STATE <= S_NACK_UNSET_SCL; else sequence_done_o_x <= '1'; NEXT_STATE <= S_IDLE; diff --git a/nxyter/source/nx_i2c_sendbyte.vhd b/nxyter/source/nx_i2c_sendbyte.vhd index 88ab011..03f525d 100644 --- a/nxyter/source/nx_i2c_sendbyte.vhd +++ b/nxyter/source/nx_i2c_sendbyte.vhd @@ -22,6 +22,7 @@ entity nx_i2c_sendbyte is SDA_OUT : out std_logic; SCL_OUT : out std_logic; SDA_IN : in std_logic; + SCL_IN : in std_logic; ACK_OUT : out std_logic ); end entity; @@ -38,12 +39,14 @@ architecture Behavioral of nx_i2c_sendbyte is signal bit_ctr : unsigned(3 downto 0); signal i2c_ack_o : std_logic; signal wait_timer_init : unsigned(11 downto 0); - + signal stretch_timeout : unsigned(19 downto 0); + signal sequence_done_o_x : std_logic; signal i2c_byte_x : unsigned(7 downto 0); signal bit_ctr_x : unsigned(3 downto 0); signal i2c_ack_o_x : std_logic; signal wait_timer_init_x : unsigned(11 downto 0); + signal stretch_timeout_x : unsigned(19 downto 0); type STATES is (S_IDLE, S_INIT, @@ -54,11 +57,14 @@ architecture Behavioral of nx_i2c_sendbyte is S_SET_SCL, S_UNSET_SCL, S_NEXT_BIT, - - S_GET_ACK, + + S_ACK_UNSET_SCL, S_ACK_SET_SCL, - S_STORE_ACK, - S_ACK_UNSET_SCL + S_STRETCH_CHECK_SCL, + S_STRETCH_WAIT_SCL, + S_STRETCH_PAUSE, + S_ACK_STORE, + S_ACK_UNSET_SCL2 ); signal STATE, NEXT_STATE : STATES; @@ -88,6 +94,7 @@ begin bit_ctr <= (others => '0'); i2c_ack_o <= '0'; wait_timer_init <= (others => '0'); + stretch_timeout <= (others => '0'); STATE <= S_IDLE; else sequence_done_o <= sequence_done_o_x; @@ -95,6 +102,7 @@ begin bit_ctr <= bit_ctr_x; i2c_ack_o <= i2c_ack_o_x; wait_timer_init <= wait_timer_init_x; + stretch_timeout <= stretch_timeout_x; STATE <= NEXT_STATE; end if; end if; @@ -113,117 +121,151 @@ begin bit_ctr_x <= bit_ctr; i2c_ack_o_x <= i2c_ack_o; wait_timer_init_x <= (others => '0'); + stretch_timeout_x <= stretch_timeout; case STATE is when S_IDLE => if (START_IN = '1') then - sda_o <= '0'; - scl_o <= '0'; - i2c_byte_x <= BYTE_IN; - NEXT_STATE <= S_INIT; + sda_o <= '0'; + scl_o <= '0'; + i2c_byte_x <= BYTE_IN; + NEXT_STATE <= S_INIT; else - NEXT_STATE <= S_IDLE; + NEXT_STATE <= S_IDLE; end if; -- INIT when S_INIT => - sda_o <= '0'; - scl_o <= '0'; - wait_timer_init_x <= I2C_SPEED srl 1; - NEXT_STATE <= S_INIT_WAIT; + sda_o <= '0'; + scl_o <= '0'; + wait_timer_init_x <= I2C_SPEED srl 1; + NEXT_STATE <= S_INIT_WAIT; when S_INIT_WAIT => - sda_o <= '0'; - scl_o <= '0'; + sda_o <= '0'; + scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_INIT_WAIT; + NEXT_STATE <= S_INIT_WAIT; else - NEXT_STATE <= S_SEND_BYTE; + NEXT_STATE <= S_SEND_BYTE; end if; -- I2C Send byte when S_SEND_BYTE => - sda_o <= '0'; - scl_o <= '0'; - bit_ctr_x <= x"7"; - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_SET_SDA; + sda_o <= '0'; + scl_o <= '0'; + bit_ctr_x <= x"7"; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_SET_SDA; when S_SET_SDA => - sda_o <= i2c_byte(7); - scl_o <= '0'; + sda_o <= i2c_byte(7); + scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_SET_SDA; + NEXT_STATE <= S_SET_SDA; else - wait_timer_init_x <= I2C_SPEED srl 1; - NEXT_STATE <= S_SET_SCL; + wait_timer_init_x <= I2C_SPEED srl 1; + NEXT_STATE <= S_SET_SCL; end if; when S_SET_SCL => - sda_o <= i2c_byte(7); + sda_o <= i2c_byte(7); if (wait_timer_done = '0') then - NEXT_STATE <= S_SET_SCL; + NEXT_STATE <= S_SET_SCL; else - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_UNSET_SCL; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_UNSET_SCL; end if; when S_UNSET_SCL => - sda_o <= i2c_byte(7); - scl_o <= '0'; + sda_o <= i2c_byte(7); + scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_UNSET_SCL; + NEXT_STATE <= S_UNSET_SCL; else - NEXT_STATE <= S_NEXT_BIT; + NEXT_STATE <= S_NEXT_BIT; end if; when S_NEXT_BIT => - sda_o <= i2c_byte(7); - scl_o <= '0'; + sda_o <= i2c_byte(7); + scl_o <= '0'; if (bit_ctr > 0) then - bit_ctr_x <= bit_ctr - 1; - i2c_byte_x <= i2c_byte sll 1; - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_SET_SDA; + bit_ctr_x <= bit_ctr - 1; + i2c_byte_x <= i2c_byte sll 1; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_SET_SDA; else - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_GET_ACK; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_ACK_UNSET_SCL; end if; - -- I2C Check ACK Sequence - when S_GET_ACK => - scl_o <= '0'; + -- Get Slave ACK bit + when S_ACK_UNSET_SCL => + scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_GET_ACK; + NEXT_STATE <= S_ACK_UNSET_SCL; else - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_ACK_SET_SCL; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_ACK_SET_SCL; end if; when S_ACK_SET_SCL => if (wait_timer_done = '0') then - NEXT_STATE <= S_ACK_SET_SCL; + NEXT_STATE <= S_ACK_SET_SCL; else - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_STORE_ACK; - end if; + NEXT_STATE <= S_STRETCH_CHECK_SCL; + end if; - when S_STORE_ACK => + -- Check for Clock Stretching + when S_STRETCH_CHECK_SCL => + if (SCL_IN = '1') then + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_ACK_STORE; + else + stretch_timeout_x <= (others => '0'); + NEXT_STATE <= S_STRETCH_WAIT_SCL; + end if; + + when S_STRETCH_WAIT_SCL => + if (SCL_IN = '0') then + if (stretch_timeout < x"30d40") then + stretch_timeout_x <= stretch_timeout + 1; + NEXT_STATE <= S_STRETCH_WAIT_SCL; + else + i2c_ack_o_x <= '0'; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_ACK_UNSET_SCL; + end if; + else + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_STRETCH_PAUSE; + end if; + + when S_STRETCH_PAUSE => if (wait_timer_done = '0') then - NEXT_STATE <= S_STORE_ACK; + NEXT_STATE <= S_STRETCH_PAUSE; else - i2c_ack_o_x <= not SDA_IN; - wait_timer_init_x <= I2C_SPEED srl 2; - NEXT_STATE <= S_ACK_UNSET_SCL; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_ACK_STORE; end if; - when S_ACK_UNSET_SCL => - scl_o <= '0'; + -- Read ACK Bit + when S_ACK_STORE => + if (wait_timer_done = '0') then + NEXT_STATE <= S_ACK_STORE; + else + i2c_ack_o_x <= not SDA_IN; + wait_timer_init_x <= I2C_SPEED srl 2; + NEXT_STATE <= S_ACK_UNSET_SCL2; + end if; + + when S_ACK_UNSET_SCL2 => + scl_o <= '0'; if (wait_timer_done = '0') then - NEXT_STATE <= S_ACK_UNSET_SCL; + NEXT_STATE <= S_ACK_UNSET_SCL2; else - sequence_done_o_x <= '1'; - NEXT_STATE <= S_IDLE; + sequence_done_o_x <= '1'; + NEXT_STATE <= S_IDLE; end if; end case; diff --git a/nxyter/source/nx_setup.vhd b/nxyter/source/nx_setup.vhd index ad586cd..2a619df 100644 --- a/nxyter/source/nx_setup.vhd +++ b/nxyter/source/nx_setup.vhd @@ -5,7 +5,6 @@ use ieee.numeric_std.all; library work; use work.trb_net_std.all; use work.trb_net_components.all; -use work.trb3_components.all; entity nx_setup is port( @@ -58,23 +57,17 @@ architecture Behavioral of nx_setup is -- Write I2C Registers type W_STATES is (W_IDLE, W_NEXT_REGISTER, - W_NOP, W_REGISTER, W_WAIT_DONE ); signal W_STATE, W_STATE_RETURN : W_STATES; - signal write_defaults_start : std_logic; - signal write_i2c_command : std_logic_vector(31 downto 0); - signal write_i2c_lock : std_logic; - signal w_register_ctr : unsigned(7 downto 0); - signal nx_ram_output_addr_i : std_logic_vector(5 downto 0); - signal nx_ram_input_addr_i : std_logic_vector(5 downto 0); - signal nx_ram_input_i : std_logic_vector(7 downto 0); - signal nx_ram_write_i : std_logic; - + signal nx_write_i2c_command : std_logic_vector(31 downto 0); + signal nx_write_i2c_lock : std_logic; + signal w_register_ctr : unsigned(5 downto 0); + -- Read I2C Registers type R_STATES is (R_IDLE, R_REGISTER, @@ -84,46 +77,82 @@ architecture Behavioral of nx_setup is signal R_STATE, R_STATE_RETURN : R_STATES; - signal read_defaults_start : std_logic; - signal read_i2c_command : std_logic_vector(31 downto 0); - signal read_i2c_lock : std_logic; - signal r_register_ctr : unsigned(7 downto 0); - - -- RAM Handler - signal nx_ram_input_addr : std_logic_vector(5 downto 0); - signal nx_ram_input : std_logic_vector(7 downto 0); - signal nx_ram_write : std_logic; + signal nx_read_i2c_command : std_logic_vector(31 downto 0); + signal nx_read_i2c_lock : std_logic; + signal r_register_ctr : unsigned(5 downto 0); + + -- Write DAC I2C Registers + type DW_STATES is (DW_IDLE, + DW_NEXT_REGISTER, + DW_REGISTER, + DW_WAIT_DONE + ); + signal DW_STATE, DW_STATE_RETURN : DW_STATES; + + signal dac_write_i2c_command : std_logic_vector(31 downto 0); + signal dac_write_i2c_lock : std_logic; + signal w_fifo_ctr : unsigned(7 downto 0); - signal nx_ram_output_addr : std_logic_vector(5 downto 0); - signal nx_ram_output : std_logic_vector(7 downto 0); + -- Read DAC I2C Registers + type DR_STATES is (DR_IDLE, + DR_REGISTER, + DR_WRITE_BACK, + DR_NEXT_REGISTER, + DR_WAIT_DONE + ); + signal DR_STATE, DR_STATE_RETURN : DR_STATES; + + + signal dac_read_i2c_command : std_logic_vector(31 downto 0); + signal dac_read_i2c_lock : std_logic; + signal r_fifo_ctr : unsigned(7 downto 0); + -- TRBNet Slave Bus signal slv_data_out_o : std_logic_vector(31 downto 0); signal slv_no_more_data_o : std_logic; signal slv_unknown_addr_o : std_logic; signal slv_ack_o : std_logic; - signal nx_ram_output_addr_s : std_logic_vector(5 downto 0); - signal nx_ram_input_addr_s : std_logic_vector(5 downto 0); - signal nx_ram_input_s : std_logic_vector(7 downto 0); - signal nx_ram_write_s : std_logic; + signal read_nx_i2c_all_start : std_logic; + signal write_nx_i2c_all_start : std_logic; + + signal read_dac_all_start : std_logic; + signal write_dac_all_start : std_logic; + + -- I2C Register Ram + type i2c_ram_t is array(0 to 45) of std_logic_vector(7 downto 0); + signal i2c_ram : i2c_ram_t; + signal i2c_ram_write_0 : std_logic; + signal i2c_ram_write_1 : std_logic; + signal i2c_ram_input_addr_0 : unsigned(5 downto 0); + signal i2c_ram_input_addr_1 : unsigned(5 downto 0); + signal i2c_ram_input_0 : std_logic_vector(7 downto 0); + signal i2c_ram_input_1 : std_logic_vector(7 downto 0); - signal register_mem_read_s : std_logic; - signal register_mem_read : std_logic; - type register_access_type_t is array(0 to 45) of std_logic; constant register_access_type : register_access_type_t := - ('1','1','1','1','1','1','1','1', -- 7 - '1','1','1','1','1','1','1','1', -- 15 - '1','1','1','1','1','1','1','1', -- 23 - '1','1','1','1','1','1','0','0', -- 31 - '1','1','0','0','0','0','1','1', --39 - '0','0','1','1','1','1' -- 45 + ('1', '1', '1', '1', '1', '1', '1', '1', -- 0 -> 7 + '1', '1', '1', '1', '1', '1', '1', '1', -- 8 -> 15 + '1', '1', '1', '1', '1', '1', '1', '1', -- 16 -> 23 + '1', '1', '1', '1', '1', '1', '0', '0', -- 24 -> 31 + '1', '1', '0', '0', '0', '0', '1', '1', -- 32 -> 39 + '0', '0', '0', '1', '1', '1' -- 40 -> 45 ); - - - signal read_write_ding : std_logic; + -- DAC Trim FIFO RAM + type dac_ram_t is array(0 to 129) of std_logic_vector(5 downto 0); + signal dac_ram : dac_ram_t; + signal dac_ram_write_0 : std_logic; + signal dac_ram_write_1 : std_logic; + signal dac_ram_input_addr_0 : unsigned(7 downto 0); + signal dac_ram_input_addr_1 : unsigned(7 downto 0); + signal dac_ram_input_0 : std_logic_vector(5 downto 0); + signal dac_ram_input_1 : std_logic_vector(5 downto 0); + + signal ctr : std_logic_vector(5 downto 0); + signal i2c_ram_write_d : std_logic; + signal dac_ram_write_d : std_logic; begin ----------------------------------------------------------------------------- @@ -131,45 +160,73 @@ begin ----------------------------------------------------------------------------- DEBUG_OUT(0) <= CLK_IN; - DEBUG_OUT(1) <= read_defaults_start; - DEBUG_OUT(2) <= write_defaults_start; - DEBUG_OUT(3) <= i2c_lock_o; - DEBUG_OUT(4) <= i2c_command_busy; - DEBUG_OUT(5) <= i2c_command_done; - DEBUG_OUT(6) <= I2C_COMMAND_BUSY_IN; - DEBUG_OUT(7) <= register_mem_read_s; - DEBUG_OUT(8) <= register_mem_read; - DEBUG_OUT(15 downto 9) <= (others => '0'); + DEBUG_OUT(1) <= read_nx_i2c_all_start; + DEBUG_OUT(2) <= write_nx_i2c_all_start; + DEBUG_OUT(3) <= read_dac_all_start; + DEBUG_OUT(4) <= write_dac_all_start; + + DEBUG_OUT(5) <= i2c_lock_o; + DEBUG_OUT(6) <= i2c_command_busy; + DEBUG_OUT(7) <= i2c_command_done; + DEBUG_OUT(8) <= I2C_COMMAND_BUSY_IN; + + DEBUG_OUT(9) <= i2c_ram_write_d; + DEBUG_OUT(10) <= i2c_ram_write_0; + DEBUG_OUT(11) <= i2c_ram_write_1; + DEBUG_OUT(12) <= dac_ram_write_d; + DEBUG_OUT(13) <= dac_ram_write_0; + DEBUG_OUT(14) <= dac_ram_write_1; + DEBUG_OUT(15) <= '0'; + + --DEBUG_OUT(14 downto 9) <= ctr; + ctr <= std_logic_vector(r_register_ctr) or std_logic_vector(w_register_ctr); ----------------------------------------------------------------------------- - - -- Simple RAM to hold all nXyter I2C register settings - - ram_dp_1: ram_dp - generic map ( - depth => 6, - width => 8 - ) - port map ( - CLK => CLK_IN, - wr1 => nx_ram_write, - a1 => nx_ram_input_addr, - dout1 => open, - din1 => nx_ram_input, - a2 => nx_ram_output_addr, - dout2 => nx_ram_output - ); - - nx_ram_output_addr <= nx_ram_output_addr_s or nx_ram_output_addr_i; - nx_ram_input_addr <= nx_ram_input_addr_s or nx_ram_input_addr_i; - nx_ram_input <= nx_ram_input_s or nx_ram_input_i; - nx_ram_write <= nx_ram_write_s or nx_ram_write_i; - - ---------------------------------------------------------------------- + PROC_I2C_RAM_WRITE_HANDLER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + i2c_ram_write_d <= '0'; + else + i2c_ram_write_d <= '0'; + if (i2c_ram_write_0 = '1') then + i2c_ram(to_integer(i2c_ram_input_addr_0)) <= i2c_ram_input_0; + i2c_ram_write_d <= '1'; + elsif (i2c_ram_write_1 = '1') then + i2c_ram(to_integer(i2c_ram_input_addr_1)) <= i2c_ram_input_1; + i2c_ram_write_d <= '1'; + end if; + end if; + end if; + end process PROC_I2C_RAM_WRITE_HANDLER; - i2c_lock_o <= write_i2c_lock or read_i2c_lock; - i2c_command <= write_i2c_command or read_i2c_command; + PROC_DAC_RAM_WRITE_HANDLER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + dac_ram_write_d <= '0'; + else + dac_ram_write_d <= '0'; + if (dac_ram_write_0 = '1') then + dac_ram(to_integer(dac_ram_input_addr_0)) <= dac_ram_input_0; + dac_ram_write_d <= '1'; + elsif (dac_ram_write_1 = '1') then + dac_ram(to_integer(dac_ram_input_addr_1)) <= dac_ram_input_1; + dac_ram_write_d <= '1'; + end if; + end if; + end if; + end process PROC_DAC_RAM_WRITE_HANDLER; + + ----------------------------------------------------------------------------- + + i2c_lock_o <= nx_write_i2c_lock or + nx_read_i2c_lock or + dac_read_i2c_lock; + i2c_command <= nx_write_i2c_command or + nx_read_i2c_command or + dac_read_i2c_command; PROC_SEND_I2C_COMMAND: process(CLK_IN) begin @@ -222,240 +279,328 @@ begin end if; end process PROC_SEND_I2C_COMMAND; -PROC_WRITE_REGISTERS: process(CLK_IN) + ----------------------------------------------------------------------------- + + PROC_READ_NX_REGISTERS: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - write_i2c_lock <= '0'; - write_i2c_command <= (others => '0'); - w_register_ctr <= (others => '0'); + nx_read_i2c_command <= (others => '0'); + nx_read_i2c_lock <= '0'; + i2c_ram_input_0 <= (others => '0'); + i2c_ram_input_addr_0 <= (others => '0'); + i2c_ram_write_0 <= '0'; + r_register_ctr <= (others => '0'); - nx_ram_output_addr_i <= (others => '0'); - - W_STATE_RETURN <= W_IDLE; - W_STATE <= W_IDLE; + R_STATE_RETURN <= R_IDLE; + R_STATE <= R_IDLE; else - write_i2c_command <= (others => '0'); - write_i2c_lock <= '1'; + nx_read_i2c_command <= (others => '0'); + nx_read_i2c_lock <= '1'; + i2c_ram_input_0 <= (others => '0'); + i2c_ram_input_addr_0 <= (others => '0'); + i2c_ram_write_0 <= '0'; + + case R_STATE is + when R_IDLE => + if (read_nx_i2c_all_start = '1') then + R_STATE <= R_REGISTER; + else + nx_read_i2c_lock <= '0'; + R_STATE <= R_IDLE; + end if; + r_register_ctr <= (others => '0'); + + when R_REGISTER => + if (register_access_type(to_integer(r_register_ctr)) = '1') then + nx_read_i2c_command(31 downto 16) <= x"ff08"; + nx_read_i2c_command(15 downto 14) <= (others => '0'); + nx_read_i2c_command(13 downto 8) <= r_register_ctr; + nx_read_i2c_command( 7 downto 0) <= (others => '0'); + R_STATE_RETURN <= R_NEXT_REGISTER; + R_STATE <= R_WAIT_DONE; + else + R_STATE <= R_NEXT_REGISTER; + end if; + + when R_NEXT_REGISTER => + if (register_access_type(to_integer(r_register_ctr)) = '1') then + i2c_ram_input_0 <= i2c_data(7 downto 0); + else + i2c_ram_input_0 <= x"be"; + end if; + i2c_ram_input_addr_0 <= r_register_ctr; + i2c_ram_write_0 <= '1'; + + if (r_register_ctr <= x"2d") then + r_register_ctr <= r_register_ctr + 1; + R_STATE <= R_REGISTER; + else + R_STATE <= R_IDLE; + end if; + + when R_WAIT_DONE => + if (i2c_command_done = '0') then + R_STATE <= R_WAIT_DONE; + else + R_STATE <= R_STATE_RETURN; + end if; + + end case; + end if; + end if; + end process PROC_READ_NX_REGISTERS; - nx_ram_output_addr_i <= (others => '0'); - read_write_ding <= '0'; + PROC_WRITE_NX_REGISTERS: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + nx_write_i2c_lock <= '0'; + nx_write_i2c_command <= (others => '0'); + w_register_ctr <= (others => '0'); + + W_STATE_RETURN <= W_IDLE; + W_STATE <= W_IDLE; + else + nx_write_i2c_command <= (others => '0'); + nx_write_i2c_lock <= '1'; case W_STATE is when W_IDLE => - if (write_defaults_start = '1') then - w_register_ctr <= (others => '0'); - W_STATE <= W_NEXT_REGISTER; + if (write_nx_i2c_all_start = '1') then + W_STATE <= W_NEXT_REGISTER; else - write_i2c_lock <= '0'; - W_STATE <= W_IDLE; + nx_write_i2c_lock <= '0'; + W_STATE <= W_IDLE; end if; + w_register_ctr <= (others => '0'); when W_NEXT_REGISTER => if (w_register_ctr <= x"2d") then - nx_ram_output_addr_i <= w_register_ctr(5 downto 0); - W_STATE <= W_NOP; + W_STATE <= W_REGISTER; else - W_STATE <= W_IDLE; + W_STATE <= W_IDLE; end if; - - when W_NOP => - read_write_ding <= '1'; - W_STATE <= W_REGISTER; when W_REGISTER => if (register_access_type( to_integer(unsigned(w_register_ctr))) = '1') then - write_i2c_command(31 downto 16) <= x"bf08"; - write_i2c_command(15 downto 8) <= w_register_ctr; - write_i2c_command(7 downto 0) <= nx_ram_output; - W_STATE_RETURN <= W_NEXT_REGISTER; - W_STATE <= W_WAIT_DONE; + nx_write_i2c_command(31 downto 16) <= x"bf08"; + nx_write_i2c_command(15 downto 14) <= (others => '0'); + nx_write_i2c_command(13 downto 8) <= w_register_ctr; + nx_write_i2c_command( 7 downto 0) <= + i2c_ram(to_integer(unsigned(w_register_ctr))); + W_STATE_RETURN <= W_NEXT_REGISTER; + W_STATE <= W_WAIT_DONE; else - W_STATE <= W_NEXT_REGISTER; + W_STATE <= W_NEXT_REGISTER; end if; - w_register_ctr <= w_register_ctr + 1; + w_register_ctr <= w_register_ctr + 1; when W_WAIT_DONE => if (i2c_command_done = '0') then - W_STATE <= W_WAIT_DONE; + W_STATE <= W_WAIT_DONE; else - W_STATE <= W_STATE_RETURN; + W_STATE <= W_STATE_RETURN; end if; end case; end if; end if; - end process PROC_WRITE_REGISTERS; + end process PROC_WRITE_NX_REGISTERS; - PROC_READ_REGISTERS: process(CLK_IN) + ----------------------------------------------------------------------------- + + PROC_READ_DAC_REGISTERS: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - read_i2c_command <= (others => '0'); - read_i2c_lock <= '0'; - r_register_ctr <= (others => '0'); - - nx_ram_input_addr_i <= (others => '0'); - nx_ram_input_i <= (others => '0'); - nx_ram_write_i <= '0'; - - R_STATE_RETURN <= R_IDLE; - R_STATE <= R_IDLE; + dac_read_i2c_command <= (others => '0'); + dac_read_i2c_lock <= '0'; + dac_ram_write_0 <= '0'; + dac_ram_input_addr_0 <= (others => '0'); + dac_ram_input_0 <= (others => '0'); + r_fifo_ctr <= (others => '0'); + + DR_STATE_RETURN <= DR_IDLE; + DR_STATE <= DR_IDLE; else - read_i2c_command <= (others => '0'); - read_i2c_lock <= '1'; - - nx_ram_input_addr_i <= (others => '0'); - nx_ram_input_i <= (others => '0'); - nx_ram_write_i <= '0'; - - case R_STATE is - when R_IDLE => - if (read_defaults_start = '1') then - r_register_ctr <= (others => '0'); - R_STATE <= R_REGISTER; - else - read_i2c_lock <= '0'; - R_STATE <= R_IDLE; - end if; - - when R_REGISTER => - if (register_access_type(to_integer(r_register_ctr)) = '1') then - read_i2c_command(31 downto 16) <= x"ff08"; - read_i2c_command(15 downto 8) <= r_register_ctr; - read_i2c_command(7 downto 0) <= (others => '0'); - R_STATE_RETURN <= R_NEXT_REGISTER; - R_STATE <= R_WAIT_DONE; - else - R_STATE <= R_NEXT_REGISTER; - end if; - - when R_NEXT_REGISTER => - if (register_access_type(to_integer(r_register_ctr)) = '1') then - nx_ram_input_i <= i2c_data(7 downto 0); + dac_read_i2c_command <= (others => '0'); + dac_read_i2c_lock <= '1'; + dac_ram_write_0 <= '0'; + dac_ram_input_addr_0 <= (others => '0'); + dac_ram_input_0 <= (others => '0'); + + case DR_STATE is + when DR_IDLE => + if (read_dac_all_start = '1') then + DR_STATE <= DR_REGISTER; else - nx_ram_input_i <= x"be"; + dac_read_i2c_lock <= '0'; + DR_STATE <= DR_IDLE; end if; - nx_ram_write_i <= '1'; - nx_ram_input_addr_i <= r_register_ctr(5 downto 0); + r_fifo_ctr <= (others => '0'); + + when DR_REGISTER => + dac_read_i2c_command(31 downto 16) <= x"ff08"; + dac_read_i2c_command(15 downto 8) <= x"2a"; -- DAC Reg 42 + dac_read_i2c_command(7 downto 0) <= (others => '0'); + DR_STATE_RETURN <= DR_WRITE_BACK; + DR_STATE <= DR_WAIT_DONE; + + when DR_WRITE_BACK => + -- Store FIFO Entry + dac_ram_input_0 <= i2c_data(5 downto 0); + dac_ram_input_addr_0 <= r_fifo_ctr; + dac_ram_write_0 <= '1'; - if (r_register_ctr <= x"2d") then - r_register_ctr <= r_register_ctr + 1; - R_STATE <= R_REGISTER; + -- Write Data Back to FIFO + dac_read_i2c_command(31 downto 16) <= x"bf08"; + dac_read_i2c_command(15 downto 8) <= x"2a"; -- DAC Reg 42 + dac_read_i2c_command(4 downto 0) <= i2c_data(4 downto 0); + dac_read_i2c_command(7 downto 5) <= (others => '0'); + DR_STATE_RETURN <= DR_NEXT_REGISTER; + DR_STATE <= DR_WAIT_DONE; + + when DR_NEXT_REGISTER => + if (r_fifo_ctr <= x"81") then + r_fifo_ctr <= r_fifo_ctr + 1; + DR_STATE <= DR_REGISTER; else - R_STATE <= R_IDLE; + DR_STATE <= DR_IDLE; end if; - when R_WAIT_DONE => + when DR_WAIT_DONE => if (i2c_command_done = '0') then - R_STATE <= R_WAIT_DONE; + DR_STATE <= DR_WAIT_DONE; else - R_STATE <= R_STATE_RETURN; + DR_STATE <= DR_STATE_RETURN; end if; end case; end if; end if; - end process PROC_READ_REGISTERS; - + end process PROC_READ_DAC_REGISTERS; + + ----------------------------------------------------------------------------- + PROC_SLAVE_BUS: process(CLK_IN) + variable mem_address : unsigned(7 downto 0) := x"00"; + begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - slv_data_out_o <= (others => '0'); - slv_no_more_data_o <= '0'; - slv_unknown_addr_o <= '0'; - slv_ack_o <= '0'; - write_defaults_start <= '0'; - read_defaults_start <= '0'; - register_mem_read_s <= '0'; - register_mem_read <= '0'; - nx_ram_output_addr_s <= (others => '0'); - nx_ram_input_addr_s <= (others => '0'); - nx_ram_input_s <= (others => '0'); - nx_ram_write_s <= '0'; + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + + read_nx_i2c_all_start <= '0'; + write_nx_i2c_all_start <= '0'; + read_dac_all_start <= '0'; + write_dac_all_start <= '0'; + + i2c_ram_input_1 <= (others => '0'); + i2c_ram_input_addr_1 <= (others => '0'); + i2c_ram_write_1 <= '0'; + dac_ram_input_1 <= (others => '0'); + dac_ram_input_addr_1 <= (others => '0'); + dac_ram_write_1 <= '0'; else - slv_data_out_o <= (others => '0'); - slv_unknown_addr_o <= '0'; - slv_no_more_data_o <= '0'; - write_defaults_start <= '0'; - read_defaults_start <= '0'; - register_mem_read_s <= '0'; - register_mem_read <= register_mem_read_s; - nx_ram_output_addr_s <= (others => '0'); - nx_ram_input_addr_s <= (others => '0'); - nx_ram_input_s <= (others => '0'); - nx_ram_write_s <= '0'; - - if (register_mem_read = '1') then - slv_data_out_o(7 downto 0) <= nx_ram_output; - slv_data_out_o(31 downto 8) <= (others => '0'); - slv_ack_o <= '1'; - + slv_data_out_o <= (others => '0'); + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + + read_nx_i2c_all_start <= '0'; + write_nx_i2c_all_start <= '0'; + read_dac_all_start <= '0'; + write_dac_all_start <= '0'; + + i2c_ram_input_1 <= (others => '0'); + i2c_ram_input_addr_1 <= (others => '0'); + i2c_ram_write_1 <= '0'; + dac_ram_input_1 <= (others => '0'); + dac_ram_input_addr_1 <= (others => '0'); + dac_ram_write_1 <= '0'; - elsif (SLV_WRITE_IN = '1') then + if (SLV_WRITE_IN = '1') then if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then if (i2c_lock_o = '1') then - slv_no_more_data_o <= '1'; - slv_ack_o <= '0'; + slv_no_more_data_o <= '1'; + slv_ack_o <= '0'; else if (register_access_type( to_integer(unsigned(SLV_ADDR_IN(5 downto 0)))) = '1') then - nx_ram_input_addr_s <= SLV_ADDR_IN(5 downto 0); - nx_ram_input_s <= SLV_DATA_IN(7 downto 0); - nx_ram_write_s <= '1'; + -- Write value to ram + i2c_ram_input_1 <= SLV_DATA_IN(7 downto 0); + i2c_ram_input_addr_1 <= unsigned(SLV_ADDR_IN(5 downto 0)); + i2c_ram_write_1 <= '1'; + slv_ack_o <= '1'; end if; - slv_ack_o <= '1'; + slv_ack_o <= '1'; + end if; + + elsif (SLV_ADDR_IN >= x"0060" and SLV_ADDR_IN <= x"00e0") then + if (i2c_lock_o = '1') then + slv_no_more_data_o <= '1'; + slv_ack_o <= '0'; + else + -- Write value to ram + mem_address := unsigned(SLV_ADDR_IN(7 downto 0)) - x"60"; + dac_ram_input_1 <= SLV_DATA_IN(5 downto 0); + dac_ram_input_addr_1 <= SLV_ADDR_IN(7 downto 0); + dac_ram_write_1 <= '1'; + slv_ack_o <= '1'; end if; else case SLV_ADDR_IN is when x"0040" => - write_defaults_start <= '1'; - slv_ack_o <= '1'; - + read_nx_i2c_all_start <= '1'; + slv_ack_o <= '1'; + when x"0041" => - read_defaults_start <= '1'; - slv_ack_o <= '1'; - + write_nx_i2c_all_start <= '1'; + slv_ack_o <= '1'; + + when x"0042" => + read_dac_all_start <= '1'; + slv_ack_o <= '1'; + + when x"0043" => + write_dac_all_start <= '1'; + slv_ack_o <= '1'; + when others => - slv_unknown_addr_o <= '1'; - slv_ack_o <= '0'; + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; end case; end if; elsif (SLV_READ_IN = '1') then if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then - nx_ram_output_addr_s <= SLV_ADDR_IN(5 downto 0); - register_mem_read_s <= '1'; - slv_ack_o <= '0'; + slv_data_out_o(7 downto 0) <= + i2c_ram(to_integer(unsigned(SLV_ADDR_IN(5 downto 0)))); + slv_data_out_o(31 downto 8) <= (others => '0'); + slv_ack_o <= '1'; + elsif (SLV_ADDR_IN >= x"0060" and SLV_ADDR_IN <= x"00e0") then + mem_address := unsigned(SLV_ADDR_IN(7 downto 0)) - x"60"; + slv_data_out_o(5 downto 0) <= dac_ram(to_integer(mem_address)); + slv_data_out_o(31 downto 6) <= (others => '0'); + slv_ack_o <= '1'; else - case SLV_ADDR_IN is - when x"0040" => - slv_data_out_o <= x"deadbeef"; - slv_ack_o <= '1'; - - when x"0041" => - slv_data_out_o <= i2c_data; - slv_ack_o <= '1'; - - when others => - slv_unknown_addr_o <= '1'; - slv_ack_o <= '0'; - - end case; + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; end if; - else - slv_ack_o <= '0'; + slv_ack_o <= '0'; end if; - + end if; end if; end process PROC_SLAVE_BUS; diff --git a/nxyter/source/nx_trigger_generator.vhd b/nxyter/source/nx_trigger_generator.vhd index d556817..b6dbb89 100644 --- a/nxyter/source/nx_trigger_generator.vhd +++ b/nxyter/source/nx_trigger_generator.vhd @@ -10,6 +10,8 @@ entity nx_trigger_generator is CLK_IN : in std_logic; RESET_IN : in std_logic; + TRIGGER_IN : in std_logic; + TRIGGER_OUT : out std_logic; TS_RESET_OUT : out std_logic; TESTPULSE_OUT : out std_logic; @@ -38,6 +40,7 @@ architecture Behavioral of nx_trigger_generator is signal trigger_o : std_logic; signal ts_reset_o : std_logic; signal testpulse_o : std_logic; + signal extern_trigger : std_logic; type STATES is (S_IDLE, S_NEXT_CYCLE, @@ -55,7 +58,7 @@ architecture Behavioral of nx_trigger_generator is signal reg_trigger_period : unsigned(15 downto 0); signal reg_testpulse_length : unsigned(15 downto 0); signal reg_trigger_num_cycles : unsigned(7 downto 0); - signal reg_reset_on : std_logic; + signal reg_ts_reset_on : std_logic; begin @@ -66,7 +69,8 @@ begin DEBUG_OUT(3) <= wait_timer_done; DEBUG_OUT(4) <= ts_reset_o; DEBUG_OUT(5) <= testpulse_o; - DEBUG_OUT(7 downto 6) <= (others => '0'); + DEBUG_OUT(6) <= TRIGGER_IN; + DEBUG_OUT(7) <= extern_trigger; DEBUG_OUT(15 downto 8) <= trigger_cycle_ctr; -- Timer @@ -94,26 +98,33 @@ begin ts_reset_o <= '0'; wait_timer_init <= (others => '0'); trigger_cycle_ctr <= (others => '0'); + extern_trigger <= '0'; STATE <= S_IDLE; else trigger_o <= '0'; testpulse_o <= '0'; ts_reset_o <= '0'; wait_timer_init <= (others => '0'); - trigger_cycle_ctr <= trigger_cycle_ctr; case STATE is when S_IDLE => if (start_cycle = '1') then trigger_cycle_ctr <= reg_trigger_num_cycles; - if (reg_reset_on = '1') then + if (reg_ts_reset_on = '1') then ts_reset_o <= '1'; wait_timer_init <= reg_trigger_period; STATE <= S_WAIT_TRIGGER_END; else STATE <= S_NEXT_CYCLE; end if; + extern_trigger <= '0'; + elsif (TRIGGER_IN = '1') then + trigger_cycle_ctr <= (others => '0'); + wait_timer_init <= reg_testpulse_length; + extern_trigger <= '1'; + STATE <= S_SET_TESTPULSE; else + extern_trigger <= '0'; STATE <= S_IDLE; end if; @@ -137,7 +148,11 @@ begin if (wait_timer_done = '0') then STATE <= S_SET_TESTPULSE; else - wait_timer_init <= reg_trigger_period - reg_testpulse_length; + if (extern_trigger = '0') then + wait_timer_init <= reg_trigger_period - reg_testpulse_length; + else + wait_timer_init <= x"0001"; + end if; STATE <= S_WAIT_TRIGGER_END; end if; @@ -164,7 +179,7 @@ begin reg_trigger_period <= x"00ff"; reg_trigger_num_cycles <= x"01"; reg_testpulse_length <= (others => '0'); - reg_reset_on <= '0'; + reg_ts_reset_on <= '0'; slv_data_out_o <= (others => '0'); slv_no_more_data_o <= '0'; slv_unknown_addr_o <= '0'; @@ -192,7 +207,7 @@ begin reg_testpulse_length <= unsigned(SLV_DATA_IN(15 downto 0)); slv_ack_o <= '1'; when x"0004" => - reg_reset_on <= SLV_DATA_IN(0); + reg_ts_reset_on <= SLV_DATA_IN(0); slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; @@ -214,7 +229,7 @@ begin std_logic_vector(reg_testpulse_length); slv_ack_o <= '1'; when x"0004" => - slv_data_out_o(0) <= reg_reset_on; + slv_data_out_o(0) <= reg_ts_reset_on; slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; diff --git a/nxyter/source/nx_trigger_handler.vhd b/nxyter/source/nx_trigger_handler.vhd index 9cd632e..8bec403 100644 --- a/nxyter/source/nx_trigger_handler.vhd +++ b/nxyter/source/nx_trigger_handler.vhd @@ -29,7 +29,7 @@ entity nx_trigger_handler is -- Internal FPGA Trigger INTERNAL_TRIGGER_IN : in std_logic; - + -- Trigger FeedBack TRIGGER_VALIDATE_BUSY_IN : in std_logic; LVL2_TRIGGER_BUSY_IN : in std_logic; @@ -41,6 +41,9 @@ entity nx_trigger_handler is EVENT_BUFFER_CLEAR_OUT : out std_logic; FAST_CLEAR_OUT : out std_logic; TRIGGER_BUSY_OUT : out std_logic; + + -- Pulser + TRIGGER_TESTPULSE_OUT : out std_logic; -- Slave bus SLV_READ_IN : in std_logic; @@ -63,11 +66,12 @@ architecture Behavioral of nx_trigger_handler is signal validate_trigger_o : std_logic; signal timestamp_hold : std_logic; signal lvl2_trigger_o : std_logic; - signal evt_buffer_clear_o : std_logic; + signal event_buffer_clear_o : std_logic; signal fast_clear_o : std_logic; signal trigger_busy_o : std_logic; signal fee_trg_release_o : std_logic; signal fee_trg_statusbits_o : std_logic_vector(31 downto 0); + signal trigger_testpulse_o : std_logic; type STATES is (S_IDLE, S_CTS_TRIGGER, @@ -83,11 +87,12 @@ architecture Behavioral of nx_trigger_handler is -- Timestamp Hold Handler type TS_STATES is (TS_IDLE, - TS_WAIT_TIMER_DONE - ); + TS_WAIT_TIMER_DONE + ); signal TS_STATE : TS_STATES; signal timestamp_hold_o : std_logic; + signal wait_timer_reset : std_logic; signal wait_timer_init : unsigned(7 downto 0); signal wait_timer_done : std_logic; @@ -98,6 +103,7 @@ architecture Behavioral of nx_trigger_handler is signal slv_ack_o : std_logic; signal reg_timestamp_hold_delay : unsigned(7 downto 0); + signal reg_testpulse_enable : std_logic; begin @@ -112,7 +118,7 @@ begin DEBUG_OUT(6) <= validate_trigger_o; DEBUG_OUT(7) <= timestamp_hold_o; DEBUG_OUT(8) <= lvl2_trigger_o; - DEBUG_OUT(9) <= evt_buffer_clear_o; + DEBUG_OUT(9) <= event_buffer_clear_o; DEBUG_OUT(10) <= fee_trg_release_o; DEBUG_OUT(11) <= trigger_busy_o; @@ -125,11 +131,13 @@ begin ) port map ( CLK_IN => CLK_IN, - RESET_IN => RESET_IN, + RESET_IN => wait_timer_reset, TIMER_START_IN => wait_timer_init, TIMER_DONE_OUT => wait_timer_done ); + wait_timer_reset <= RESET_IN or fast_clear_o; + ----------------------------------------------------------------------------- -- Trigger Handler ----------------------------------------------------------------------------- @@ -143,8 +151,10 @@ begin lvl2_trigger_o <= '0'; fee_trg_release_o <= '0'; fee_trg_statusbits_o <= (others => '0'); - evt_buffer_clear_o <= '0'; + fast_clear_o <= '0'; + event_buffer_clear_o <= '0'; trigger_busy_o <= '0'; + trigger_testpulse_o <= '0'; STATE <= S_IDLE; else validate_trigger_o <= '0'; @@ -152,87 +162,93 @@ begin lvl2_trigger_o <= '0'; fee_trg_release_o <= '0'; fee_trg_statusbits_o <= (others => '0'); - evt_buffer_clear_o <= '0'; + fast_clear_o <= '0'; + event_buffer_clear_o <= '0'; trigger_busy_o <= '1'; - - case STATE is - when S_IDLE => + trigger_testpulse_o <= '0'; + + if (LVL1_INVALID_TRG_IN = '1') then + fast_clear_o <= '1'; + fee_trg_release_o <= '1'; + STATE <= S_IDLE; + else + case STATE is + when S_IDLE => + if (LVL1_VALID_NOTIMING_TRG_IN = '1') then + STATE <= S_WAIT_TRG_DATA_VALID; + + elsif (LVL1_VALID_TIMING_TRG_IN = '1') then + if (NXYTER_OFFLINE_IN = '1') then + STATE <= S_WAIT_TRG_DATA_VALID; + else + STATE <= S_CTS_TRIGGER; + end if; + elsif (INTERNAL_TRIGGER_IN = '1') then + STATE <= S_INTERNAL_TRIGGER; + else + trigger_busy_o <= '0'; + STATE <= S_IDLE; + end if; + + -- CTS Trigger Handler + when S_CTS_TRIGGER => + event_buffer_clear_o <= '1'; + validate_trigger_o <= '1'; + timestamp_hold <= '1'; + lvl2_trigger_o <= '1'; + if (reg_testpulse_enable = '1') then + trigger_testpulse_o <= '1'; + end if; + STATE <= S_WAIT_TRG_DATA_VALID; + + when S_WAIT_TRG_DATA_VALID => + if (LVL1_TRG_DATA_VALID_IN = '0') then + STATE <= S_WAIT_TRG_DATA_VALID; + else + STATE <= S_WAIT_LVL2_TRIGGER_DONE; + end if; - if (LVL1_VALID_NOTIMING_TRG_IN = '1') then - STATE <= S_WAIT_TRG_DATA_VALID; + when S_WAIT_LVL2_TRIGGER_DONE => + if (LVL2_TRIGGER_BUSY_IN = '1') then + STATE <= S_WAIT_LVL2_TRIGGER_DONE; + else + STATE <= S_FEE_TRIGGER_RELEASE; + end if; - elsif (LVL1_INVALID_TRG_IN = '1') then + when S_FEE_TRIGGER_RELEASE => fee_trg_release_o <= '1'; - STATE <= S_IDLE; + STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; - elsif (LVL1_VALID_TIMING_TRG_IN = '1') then - if (NXYTER_OFFLINE_IN = '1') then - STATE <= S_WAIT_TRG_DATA_VALID; + when S_WAIT_FEE_TRIGGER_RELEASE_ACK => + if (LVL1_TRG_DATA_VALID_IN = '1') then + STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; else - STATE <= S_CTS_TRIGGER; + STATE <= S_IDLE; end if; - elsif (INTERNAL_TRIGGER_IN = '1') then - STATE <= S_INTERNAL_TRIGGER; - else - trigger_busy_o <= '0'; - STATE <= S_IDLE; - end if; - - -- CTS Trigger Handler - when S_CTS_TRIGGER => - evt_buffer_clear_o <= '1'; - validate_trigger_o <= '1'; - timestamp_hold <= '1'; - lvl2_trigger_o <= '1'; - STATE <= S_WAIT_TRG_DATA_VALID; - - when S_WAIT_TRG_DATA_VALID => - if (LVL1_TRG_DATA_VALID_IN = '0') then - STATE <= S_WAIT_TRG_DATA_VALID; - else - STATE <= S_WAIT_LVL2_TRIGGER_DONE; - end if; - - when S_WAIT_LVL2_TRIGGER_DONE => - if (LVL2_TRIGGER_BUSY_IN = '1') then - STATE <= S_WAIT_LVL2_TRIGGER_DONE; - else - STATE <= S_FEE_TRIGGER_RELEASE; - end if; - - when S_FEE_TRIGGER_RELEASE => - fee_trg_release_o <= '1'; - STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; - when S_WAIT_FEE_TRIGGER_RELEASE_ACK => - if (LVL1_TRG_DATA_VALID_IN = '1') then - STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; - else - STATE <= S_IDLE; - end if; - - -- Internal Trigger Handler - when S_INTERNAL_TRIGGER => - validate_trigger_o <= '1'; - timestamp_hold <= '1'; - evt_buffer_clear_o <= '1'; - STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; - - when S_WAIT_TRIGGER_VALIDATE_ACK => - if (TRIGGER_VALIDATE_BUSY_IN = '0') then - STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; - else - STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; - end if; - - when S_WAIT_TRIGGER_VALIDATE_DONE => - if (TRIGGER_VALIDATE_BUSY_IN = '1') then - STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; - else - STATE <= S_IDLE; - end if; - - end case; + -- Internal Trigger Handler + when S_INTERNAL_TRIGGER => + validate_trigger_o <= '1'; + timestamp_hold <= '1'; + event_buffer_clear_o <= '1'; + STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; + + when S_WAIT_TRIGGER_VALIDATE_ACK => + if (TRIGGER_VALIDATE_BUSY_IN = '0') then + STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; + else + STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; + end if; + + when S_WAIT_TRIGGER_VALIDATE_DONE => + if (TRIGGER_VALIDATE_BUSY_IN = '1') then + STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; + else + STATE <= S_IDLE; + end if; + + end case; + end if; end if; end if; end process PROC_TRIGGER_HANDLER; @@ -241,12 +257,12 @@ begin begin if( rising_edge(CLK_IN) ) then if (RESET_IN = '1' or NXYTER_OFFLINE_IN = '1') then - wait_timer_init <= (others => '0'); - timestamp_hold_o <= '0'; - TS_STATE <= TS_IDLE; + wait_timer_init <= (others => '0'); + timestamp_hold_o <= '0'; + TS_STATE <= TS_IDLE; else - wait_timer_init <= (others => '0'); - timestamp_hold_o <= '0'; + wait_timer_init <= (others => '0'); + timestamp_hold_o <= '0'; case TS_STATE is @@ -285,6 +301,7 @@ begin slv_unknown_addr_o <= '0'; slv_ack_o <= '0'; reg_timestamp_hold_delay <= x"01"; + reg_testpulse_enable <= '0'; else slv_unknown_addr_o <= '0'; slv_no_more_data_o <= '0'; @@ -298,6 +315,10 @@ begin reg_timestamp_hold_delay <= unsigned(SLV_DATA_IN(7 downto 0)); end if; slv_ack_o <= '1'; + + when x"0001" => + reg_testpulse_enable <= SLV_DATA_IN(0); + slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; @@ -313,6 +334,11 @@ begin slv_data_out_o(31 downto 8) <= (others => '0'); slv_ack_o <= '1'; + when x"0001" => + slv_data_out_o(0) <= reg_testpulse_enable; + slv_data_out_o(31 downto 1) <= (others => '0'); + slv_ack_o <= '1'; + when others => slv_unknown_addr_o <= '1'; @@ -331,12 +357,14 @@ begin VALIDATE_TRIGGER_OUT <= validate_trigger_o; TIMESTAMP_HOLD_OUT <= timestamp_hold_o; LVL2_TRIGGER_OUT <= lvl2_trigger_o; - EVENT_BUFFER_CLEAR_OUT <= evt_buffer_clear_o; + EVENT_BUFFER_CLEAR_OUT <= event_buffer_clear_o; FAST_CLEAR_OUT <= fast_clear_o; TRIGGER_BUSY_OUT <= trigger_busy_o; FEE_TRG_RELEASE_OUT <= fee_trg_release_o; FEE_TRG_STATUSBITS_OUT <= fee_trg_statusbits_o; + TRIGGER_TESTPULSE_OUT <= trigger_testpulse_o; + -- Slave Bus SLV_DATA_OUT <= slv_data_out_o; SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; diff --git a/nxyter/source/nx_trigger_validate.vhd b/nxyter/source/nx_trigger_validate.vhd index 5915259..600b3c3 100644 --- a/nxyter/source/nx_trigger_validate.vhd +++ b/nxyter/source/nx_trigger_validate.vhd @@ -97,10 +97,13 @@ architecture Behavioral of nx_trigger_validate is signal t_data_o : std_logic_vector(31 downto 0); signal t_data_clk_o : std_logic; signal busy_time_ctr : unsigned(11 downto 0); - - -- Timer - signal wait_timer_done : std_logic; + signal busy_time_min_done : std_logic; + signal wait_timer_reset : std_logic; + -- Timer + signal timer_reset : std_logic; + signal wait_timer_done : std_logic; + -- Histogram signal histogram_fill_o : std_logic; signal histogram_bin_o : std_logic_vector(6 downto 0); @@ -123,16 +126,19 @@ begin -- Debug Line DEBUG_OUT(0) <= CLK_IN; --- DEBUG_OUT(2) <= trigger_busy_o; --- DEBUG_OUT(3) <= channel_all_done; --- DEBUG_OUT(4) <= data_clk_o; --- DEBUG_OUT(5) <= t_data_clk_o; --- DEBUG_OUT(6) <= out_of_window_l; - --DEBUG_OUT(7) <= out_of_window_h; - --DEBUG_OUT(8) <= NX_TOKEN_RETURN_IN; - --DEBUG_OUT(9) <= NX_NOMORE_DATA_IN; - --DEBUG_OUT(10) <= store_to_fifo; - DEBUG_OUT(15 downto 1) <= SLV_ADDR_IN(15 downto 1); + DEBUG_OUT(2) <= trigger_busy_o; + DEBUG_OUT(3) <= channel_all_done; + DEBUG_OUT(4) <= data_clk_o; + DEBUG_OUT(5) <= t_data_clk_o; + DEBUG_OUT(6) <= out_of_window_l; + DEBUG_OUT(7) <= out_of_window_h; + DEBUG_OUT(8) <= NX_TOKEN_RETURN_IN; + DEBUG_OUT(9) <= NX_NOMORE_DATA_IN; + DEBUG_OUT(10) <= store_to_fifo; + DEBUG_OUT(11) <= wait_timer_done; + DEBUG_OUT(12) <= timer_reset; + DEBUG_OUT(13) <= busy_time_min_done; + DEBUG_OUT(15 downto 14) <= (others => '0'); -- Timer nx_timer_1: nx_timer @@ -141,11 +147,13 @@ begin ) port map ( CLK_IN => CLK_IN, - RESET_IN => RESET_IN, + RESET_IN => timer_reset, TIMER_START_IN => wait_timer_init, TIMER_DONE_OUT => wait_timer_done ); + timer_reset <= RESET_IN or wait_timer_reset; + -- Sync Timestamp Ref PROC_SYNC_TIMESTAMP_REF: process (CLK_IN) begin @@ -169,7 +177,8 @@ begin variable window_lower_thr : unsigned(11 downto 0); variable window_upper_thr : unsigned(11 downto 0); variable deltaT : unsigned(11 downto 0); - + variable deltaTStore : unsigned(11 downto 0); + begin if( rising_edge(CLK_IN) ) then if (RESET_IN = '1') then @@ -195,10 +204,11 @@ begin window_lower_thr := trigger_window_delay; window_upper_thr := window_lower_thr + trigger_window_width; deltaT := unsigned(TIMESTAMP_IN(13 downto 2)) - ts_ref; - + deltaTStore := deltaT - window_lower_thr; + window_lower_thr_r <= window_lower_thr; window_upper_thr_r <= window_upper_thr; - + case readout_mode is when x"0" => -- RefValue + valid and window filter @@ -219,46 +229,56 @@ begin -- IN LUT-Data bit setzten. channel_index <= CHANNEL_IN; ch_status_cmd_pr <= CS_SET_WAIT; - - data_o(11 downto 0) <= deltaT; - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= '0'; - data_clk_o <= '1'; + + data_o( 6 downto 0) <= CHANNEL_IN; + data_o(7) <= TIMESTAMP_STATUS_IN(1); + data_o( 9 downto 8) <= TIMESTAMP_IN(1 downto 0); + data_o(18 downto 10) <= deltaTStore(8 downto 0); + data_o(30 downto 19) <= ADC_DATA_IN; + data_o(31) <= TIMESTAMP_STATUS_IN(2); + data_clk_o <= '1'; end if; end if; when x"1" => -- RefValue + valid filter if (TIMESTAMP_STATUS_IN(1) = '0') then - data_o(11 downto 0) <= deltaT; - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= '0'; + data_o( 6 downto 0) <= CHANNEL_IN; + data_o(7) <= TIMESTAMP_STATUS_IN(1); + data_o( 9 downto 8) <= TIMESTAMP_IN(1 downto 0); + data_o(18 downto 10) <= deltaTStore(8 downto 0); + data_o(30 downto 19) <= ADC_DATA_IN; + data_o(31) <= TIMESTAMP_STATUS_IN(2); data_clk_o <= '1'; end if; when x"3" => -- RefValue + valid filter if (TIMESTAMP_STATUS_IN(1) = '0') then - data_o(11 downto 0) <= TIMESTAMP_IN(13 downto 2); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= '0'; + data_o( 6 downto 0) <= CHANNEL_IN; + data_o(7) <= TIMESTAMP_STATUS_IN(1); + data_o( 9 downto 8) <= TIMESTAMP_IN(1 downto 0); + data_o(18 downto 10) <= deltaTStore(8 downto 0); + data_o(30 downto 19) <= ADC_DATA_IN; + data_o(31) <= TIMESTAMP_STATUS_IN(2); data_clk_o <= '1'; end if; when x"4" => -- RawValue - data_o(11 downto 0) <= TIMESTAMP_IN(13 downto 2); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= '0'; + data_o( 6 downto 0) <= CHANNEL_IN; + data_o(7) <= TIMESTAMP_STATUS_IN(1); + data_o( 9 downto 8) <= TIMESTAMP_IN(1 downto 0); + data_o(18 downto 10) <= deltaTStore(8 downto 0); + data_o(30 downto 19) <= ADC_DATA_IN; + data_o(31) <= TIMESTAMP_STATUS_IN(2); data_clk_o <= '1'; when x"5" => -- RawValue + valid filter if (TIMESTAMP_STATUS_IN(1) = '0') then - data_o(11 downto 0) <= TIMESTAMP_IN(13 downto 2); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= '0'; + data_o( 6 downto 0) <= CHANNEL_IN; + data_o(7) <= TIMESTAMP_STATUS_IN(1); + data_o( 9 downto 8) <= TIMESTAMP_IN(1 downto 0); + data_o(18 downto 10) <= deltaTStore(8 downto 0); + data_o(30 downto 19) <= ADC_DATA_IN; + data_o(31) <= TIMESTAMP_STATUS_IN(2); data_clk_o <= '1'; end if; @@ -281,24 +301,27 @@ begin ----------------------------------------------------------------------------- PROC_TRIGGER_HANDLER: process(CLK_IN) - variable min_validation_time : unsigned(23 downto 0); + variable min_validation_time : unsigned(11 downto 0); begin if( rising_edge(CLK_IN) ) then - if (RESET_IN = '1') then + if (RESET_IN = '1' or FAST_CLEAR_IN = '1') then store_to_fifo <= '0'; trigger_busy_o <= '0'; nomore_data_o <= '0'; wait_timer_init <= (others => '0'); + wait_timer_reset <= '0'; t_data_o <= (others => '0'); t_data_clk_o <= '0'; busy_time_ctr <= (others => '0'); + busy_time_min_done <= '0'; token_return_ctr <= '0'; ch_status_cmd_tr <= CS_RESET; STATE <= S_IDLE; else store_to_fifo <= '0'; wait_timer_init <= (others => '0'); + wait_timer_reset <= '0'; trigger_busy_o <= '1'; nomore_data_o <= '0'; t_data_o <= (others => '0'); @@ -306,11 +329,10 @@ begin ch_status_cmd_tr <= CS_NONE; min_validation_time := x"020" + - (trigger_window_delay * 2 + - trigger_window_delay / 2) + - (trigger_window_width * 2 + - trigger_window_width / 2); - + (trigger_window_delay / 2) + + (trigger_window_width / 2); + + case STATE is when S_IDLE => @@ -347,13 +369,14 @@ begin busy_time_ctr > min_validation_time(11 downto 0)) ) then + wait_timer_reset <= '1'; STATE <= S_WRITE_TRAILER; else store_to_fifo <= '1'; STATE <= S_WAIT_PROCESS_END; -- Check Token_Return - if (busy_time_ctr > min_validation_time(11 downto 0)) then + if (busy_time_ctr > min_validation_time) then if (readout_mode = x"0" and NX_TOKEN_RETURN_IN = '1') then if (token_return_ctr = '1') then ch_status_cmd_tr <= CS_TOKEN_UPDATE; @@ -379,6 +402,11 @@ begin busy_time_ctr <= busy_time_ctr + 1; end if; + if (busy_time_ctr > min_validation_time) then + busy_time_min_done <= '1'; + else + busy_time_min_done <= '0'; + end if; end if; end if; end process PROC_TRIGGER_HANDLER; diff --git a/nxyter/source/nxyter_components.vhd b/nxyter/source/nxyter_components.vhd index 1e00309..400d900 100644 --- a/nxyter/source/nxyter_components.vhd +++ b/nxyter/source/nxyter_components.vhd @@ -131,6 +131,7 @@ component nx_i2c_sendbyte SDA_OUT : out std_logic; SCL_OUT : out std_logic; SDA_IN : in std_logic; + SCL_IN : in std_logic; ACK_OUT : out std_logic ); end component; @@ -418,13 +419,15 @@ end component; component nx_histograms generic ( - NUM_BINS : integer); + BUS_WIDTH : integer; + ENABLE : integer + ); port ( CLK_IN : in std_logic; RESET_IN : in std_logic; RESET_HISTS_IN : in std_logic; CHANNEL_STAT_FILL_IN : in std_logic; - CHANNEL_ID_IN : in std_logic_vector(NUM_BINS - 1 downto 0); + CHANNEL_ID_IN : in std_logic_vector(BUS_WIDTH - 1 downto 0); SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; SLV_DATA_OUT : out std_logic_vector(31 downto 0); @@ -574,6 +577,7 @@ component nx_trigger_handler EVENT_BUFFER_CLEAR_OUT : out std_logic; FAST_CLEAR_OUT : out std_logic; TRIGGER_BUSY_OUT : out std_logic; + TRIGGER_TESTPULSE_OUT : out std_logic; SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; SLV_DATA_OUT : out std_logic_vector(31 downto 0); @@ -590,6 +594,7 @@ component nx_trigger_generator port ( CLK_IN : in std_logic; RESET_IN : in std_logic; + TRIGGER_IN : out std_logic; TRIGGER_OUT : out std_logic; TS_RESET_OUT : out std_logic; TESTPULSE_OUT : out std_logic; @@ -652,4 +657,25 @@ component nxyter_timestamp_sim ); end component; +type debug_array_t is array(integer range <>) of std_logic_vector(15 downto 0); + +component debug_multiplexer + generic ( + NUM_PORTS : integer range 1 to 32); + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + DEBUG_LINE_IN : in debug_array_t(0 to NUM_PORTS-1); + DEBUG_LINE_OUT : out std_logic_vector(15 downto 0); + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic + ); +end component; + end package; diff --git a/nxyter/source/nxyter_fee_board.vhd b/nxyter/source/nxyter_fee_board.vhd index 30736ff..8a89422 100644 --- a/nxyter/source/nxyter_fee_board.vhd +++ b/nxyter/source/nxyter_fee_board.vhd @@ -98,7 +98,7 @@ architecture Behavioral of nXyter_FEE_board is signal clk_250_o : std_logic; -- Bus Handler - constant NUM_PORTS : integer := 11; + constant NUM_PORTS : integer := 12; signal slv_read : std_logic_vector(NUM_PORTS-1 downto 0); signal slv_write : std_logic_vector(NUM_PORTS-1 downto 0); @@ -174,6 +174,7 @@ architecture Behavioral of nXyter_FEE_board is signal fast_clear : std_logic; signal nxyter_offline : std_logic; signal fee_trg_release_o : std_logic; + signal trigger_testpulse : std_logic; -- FPGA Timestamp signal timestamp_trigger : unsigned(11 downto 0); @@ -183,6 +184,10 @@ architecture Behavioral of nXyter_FEE_board is signal trigger_intern : std_logic; signal nx_testpulse_o : std_logic; + -- Debug Handler + constant DEBUG_NUM_PORTS : integer := 12; + signal debug_line : debug_array_t(0 to DEBUG_NUM_PORTS-1); + begin ------------------------------------------------------------------------------- @@ -243,31 +248,35 @@ begin generic map( PORT_NUMBER => NUM_PORTS, - PORT_ADDRESSES => ( 0 => x"0100", -- Control Register Handler - 1 => x"0040", -- I2C Master - 2 => x"0500", -- Data Receiver - 3 => x"0600", -- Data Buffer - 4 => x"0060", -- SPI Master - 5 => x"0140", -- Trigger Generator - 6 => x"0120", -- Data Validate - 7 => x"0160", -- Trigger Handler - 8 => x"0180", -- Trigger Validate - 9 => x"0200", -- NX Register Setup - 10 => x"0800", -- NX Histograms - others => x"0000"), - - PORT_ADDR_MASK => ( 0 => 3, -- Control Register Handler - 1 => 0, -- I2C master - 2 => 3, -- Data Receiver - 3 => 3, -- Data Buffer - 4 => 0, -- SPI Master - 5 => 3, -- Trigger Generator - 6 => 4, -- Data Validate - 7 => 1, -- Trigger Handler - 8 => 4, -- Trigger Validate - 9 => 8, -- NX Register Setup - 10 => 8, -- NX Histograms - others => 0), + PORT_ADDRESSES => ( 0 => x"0100", -- Control Register Handler + 1 => x"0040", -- I2C Master + 2 => x"0500", -- Data Receiver + 3 => x"0600", -- Data Buffer + 4 => x"0060", -- SPI Master + 5 => x"0140", -- Trigger Generator + 6 => x"0120", -- Data Validate + 7 => x"0160", -- Trigger Handler + 8 => x"0180", -- Trigger Validate + 9 => x"0200", -- NX Register Setup + 10 => x"0800", -- NX Histograms + 11 => x"0020", -- Debug Handler + others => x"0000" + ), + + PORT_ADDR_MASK => ( 0 => 3, -- Control Register Handler + 1 => 0, -- I2C master + 2 => 3, -- Data Receiver + 3 => 3, -- Data Buffer + 4 => 0, -- SPI Master + 5 => 3, -- Trigger Generator + 6 => 4, -- Data Validate + 7 => 1, -- Trigger Handler + 8 => 4, -- Trigger Validate + 9 => 8, -- NX Register Setup + 10 => 8, -- NX Histograms + 11 => 0, -- Debug Handler + others => 0 + ), PORT_MASK_ENABLE => 1 ) @@ -286,7 +295,7 @@ begin DAT_NO_MORE_DATA_OUT => REGIO_NO_MORE_DATA_OUT, DAT_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT, - -- Control Registers + -- All NXYTER Ports BUS_READ_ENABLE_OUT => slv_read, BUS_WRITE_ENABLE_OUT => slv_write, BUS_DATA_OUT => slv_data_wr, @@ -324,7 +333,7 @@ begin NX_TS_RESET_OUT => nx_ts_reset_1, OFFLINE_OUT => nxyter_offline, --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(0) ); nx_register_setup_1: nx_setup @@ -348,7 +357,7 @@ begin SLV_NO_MORE_DATA_OUT => slv_no_more_data(9), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(9), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(1) ); ------------------------------------------------------------------------------- @@ -376,7 +385,7 @@ begin SLV_NO_MORE_DATA_OUT => slv_no_more_data(1), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(1), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(2) ); ------------------------------------------------------------------------------- @@ -405,7 +414,7 @@ begin SLV_NO_MORE_DATA_OUT => slv_no_more_data(4), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(4), -- DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(3) ); ------------------------------------------------------------------------------- @@ -428,7 +437,7 @@ begin SLV_NO_MORE_DATA_OUT => open, SLV_UNKNOWN_ADDR_OUT => open, -- DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(4) ); ------------------------------------------------------------------------------- @@ -467,6 +476,8 @@ begin FAST_CLEAR_OUT => fast_clear, TRIGGER_BUSY_OUT => trigger_busy, + TRIGGER_TESTPULSE_OUT => trigger_testpulse, + SLV_READ_IN => slv_read(7), SLV_WRITE_IN => slv_write(7), SLV_DATA_OUT => slv_data_rd(7*32+31 downto 7*32), @@ -477,7 +488,7 @@ begin SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(7), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(5) ); ------------------------------------------------------------------------------- @@ -488,6 +499,7 @@ begin port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, + TRIGGER_IN => trigger_testpulse, TRIGGER_OUT => trigger_intern, TS_RESET_OUT => nx_ts_reset_2, TESTPULSE_OUT => nx_testpulse_o, @@ -500,7 +512,7 @@ begin SLV_NO_MORE_DATA_OUT => slv_no_more_data(5), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(5), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(6) ); ------------------------------------------------------------------------------- @@ -537,7 +549,7 @@ begin SLV_NO_MORE_DATA_OUT => slv_no_more_data(2), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(2), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(7) ); ------------------------------------------------------------------------------- @@ -571,7 +583,7 @@ begin SLV_NO_MORE_DATA_OUT => slv_no_more_data(6), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(6), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(8) ); ------------------------------------------------------------------------------- @@ -611,8 +623,8 @@ begin SLV_ACK_OUT => slv_ack(8), SLV_NO_MORE_DATA_OUT => slv_no_more_data(8), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(8), - DEBUG_OUT => DEBUG_LINE_OUT - --DEBUG_OUT => open + --DEBUG_OUT => DEBUG_LINE_OUT + DEBUG_OUT => debug_line(9) ); ------------------------------------------------------------------------------- @@ -652,12 +664,13 @@ begin SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(3), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(10) ); nx_histograms_1: nx_histograms generic map ( - NUM_BINS => 7 + BUS_WIDTH => 7, + ENABLE => 0 ) port map ( CLK_IN => CLK_IN, @@ -677,7 +690,7 @@ begin SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(10), --DEBUG_OUT => DEBUG_LINE_OUT - DEBUG_OUT => open + DEBUG_OUT => debug_line(11) ); ------------------------------------------------------------------------------- @@ -693,6 +706,29 @@ begin I2C_SM_RESET_OUT <= not i2c_sm_reset_o; I2C_REG_RESET_OUT <= not i2c_reg_reset_o; + + +------------------------------------------------------------------------------- +-- DEBUG Line Select +------------------------------------------------------------------------------- + debug_multiplexer_1: debug_multiplexer + generic map ( + NUM_PORTS => DEBUG_NUM_PORTS + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + DEBUG_LINE_IN => debug_line, + DEBUG_LINE_OUT => DEBUG_LINE_OUT, + SLV_READ_IN => slv_read(11), + SLV_WRITE_IN => slv_write(11), + SLV_DATA_OUT => slv_data_rd(11*32+31 downto 11*32), + SLV_DATA_IN => slv_data_wr(11*32+31 downto 11*32), + SLV_ADDR_IN => slv_addr(11*16+15 downto 11*16), + SLV_ACK_OUT => slv_ack(11), + SLV_NO_MORE_DATA_OUT => slv_no_more_data(11), + SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(11) + ); ------------------------------------------------------------------------------- -- END diff --git a/nxyter/source/registers.txt b/nxyter/source/registers.txt index 8c5e9a0..ef9beb5 100644 --- a/nxyter/source/registers.txt +++ b/nxyter/source/registers.txt @@ -5,7 +5,7 @@ 0x8103 : r/w Put nxyter into offline mode -- NX Data Validate -0x8120 : rw Invalid Frame Counter (16 bit) / w: clear all counters +0x8120 : r/w Invalid Frame Counter (16 bit) / w: clear all counters 0x8121 : r Overflow Counter (16 bit) 0x8122 : r Pileup Counter (16 bit) 0x8123 : r Parity Error Counter (16 bit) @@ -34,6 +34,7 @@ -- Trigger Handler 0x8160 : r/w Bit 15-0 : Delay Timestamp Hold signal (8bit, 10ns) +0x8161 : r/w Bit 0 : Enable Testpulse Signal (default: off) -- NX Data Receiver 0x8500 : r current Timestamp FIFO value @@ -63,11 +64,37 @@ 0x8600 : r read FIFO buffer 0x8601 : r FIFO write counter 0x8602 : r FIFO flush counter -0x8603 : r/w r: read FIFO status - w: enable/disable FIFO write +0x8603 : r read FIFO status -- I2C Master -0x8040 : Access to I2C Interface +0x8040 : Access to I2C Interface + Chip Ids: 0x08 : nXyter + 0x29 : AD7991-1 + 0x50 : EEPROM -- SPI Master 0x8060 : Access to SPI Interface + +-- NX I2C Setup Handler +0x8200 : r/w I2C Memeory Register (Depth: 0 - 45 ... 0x822c) +0x8260 : r/w DAC Register Memory (Depth: 0 - 129 ... 0x82e0) +0x8240 : w Read all I2C Registers into Memory +0x8241 : w Write all Memory to I2C Registers +0x8242 : w Read Trim DAC Register(129 deep FIFO) to Memory +0x8243 : w Write Memory to Trim DAC Register(129 deep FIFO) + +-- Debug Multiplexer +0x8020 : r/w Select Debug Entity + 0: nxyter_registers + 1: nx_setup + 2: nx_i2c_master + 3: adc_spi_master + 4: nx_fpga_timestamp + 5: nx_trigger_handler + 6: nx_trigger_generator + 7: nx_data_receiver + 8: nx_data_validate + 9: nx_trigger_validate + 10: nx_event_buffer + 11: nx_histograms + diff --git a/nxyter/trb3_periph.prj b/nxyter/trb3_periph.prj index 149adbf..87acf58 100644 --- a/nxyter/trb3_periph.prj +++ b/nxyter/trb3_periph.prj @@ -158,6 +158,7 @@ add_file -vhdl -lib "work" "source/pulse_to_level.vhd" add_file -vhdl -lib "work" "source/gray_decoder.vhd" add_file -vhdl -lib "work" "source/gray_encoder.vhd" add_file -vhdl -lib "work" "source/nx_timer.vhd" +add_file -vhdl -lib "work" "source/debug_multiplexer.vhd" add_file -vhdl -lib "work" "source/nxyter_fee_board.vhd" add_file -vhdl -lib "work" "source/nx_data_receiver.vhd" diff --git a/nxyter/trb3_periph_constraints.lpf b/nxyter/trb3_periph_constraints.lpf index 0022ba1..c93bfeb 100644 --- a/nxyter/trb3_periph_constraints.lpf +++ b/nxyter/trb3_periph_constraints.lpf @@ -76,8 +76,8 @@ PROHIBIT SECONDARY NET "NX1_CLK128_IN_c"; PROHIBIT PRIMARY NET "NX2_CLK128_IN_c"; PROHIBIT SECONDARY NET "NX2_CLK128_IN_c"; -PROHIBIT PRIMARY NET "TEST_LINE_c_0"; -PROHIBIT SECONDARY NET "TEST_LINE_c_0"; +PROHIBIT PRIMARY NET "TEST_LINE_c_0_1"; +PROHIBIT SECONDARY NET "TEST_LINE_c_0_1"; DEFINE PORT GROUP "NX1_IN" "NX1_TIMESTAMP_*"; INPUT_SETUP GROUP "NX1_IN" 3.0 ns HOLD 3.0 ns CLKPORT="NX1_CLK128_IN" ; -- 2.43.0