From a0729ac015ce27f39fcdb4ee5074fa9e01ceb53b Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Fri, 19 Mar 2010 13:14:34 +0000 Subject: [PATCH] *** empty log message *** --- special/handler_data.vhd | 25 +- special/handler_ipu.vhd | 3 +- special/handler_lvl1.vhd | 51 +-- special/handler_trigger_and_data.vhd | 107 +++++- special/slv_register.vhd | 354 +++++++++--------- special/spi_master.vhd | 512 +++++++++++++-------------- 6 files changed, 576 insertions(+), 476 deletions(-) diff --git a/special/handler_data.vhd b/special/handler_data.vhd index 0dc0cc4..177e395 100644 --- a/special/handler_data.vhd +++ b/special/handler_data.vhd @@ -18,25 +18,28 @@ entity handler_data is CLOCK : in std_logic; RESET : in std_logic; - --From LVL1 Handler - LVL1_TRG_RECEIVED_OUT : in std_logic; --TRG Info valid & FEE busy - LVL1_TRG_TYPE_OUT : in std_logic_vector(3 downto 0); --trigger type - LVL1_TRG_INFO_OUT : in std_logic_vector(23 downto 0); --further trigger details - LVL1_TRG_NUMBER_OUT : in std_logic_vector(15 downto 0); --trigger number - LVL1_BUFFER_WARN_OUT : out std_logic; --some fifos might be full soon - LVL1_BUFFER_FULL_OUT : out std_logic; --some fifos are full + --LVL1 Handler + LVL1_TRG_RECEIVED_IN : in std_logic; --TRG Info valid & FEE busy + LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); --trigger type + LVL1_TRG_INFO_IN : in std_logic_vector(23 downto 0); --further trigger details + LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); + LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); --trigger number LVL1_STATUSBITS_OUT : out std_logic_vector(31 downto 0); + LVL1_TRG_RELEASE_OUT : out std_logic; - --From FEE + --FEE FEE_DATA_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); FEE_DATA_WRITE_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); - FEE_DATA_ALMOST_FULL_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); + FEE_DATA_FINISHED_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); FEE_DATA_STATUSBITS_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); + FEE_DATA_ALMOST_FULL_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); - --To IPU Handler - IPU_DATA_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); + --IPU Handler + IPU_DATA_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER*36-1 downto 0); IPU_DATA_READ_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); IPU_DATA_EMPTY_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); + IPU_DATA_LENGTH_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER*16-1 downto 0); + IPU_HDR_DATA_OUT : out std_logic_vector(31 downto 0); IPU_HDR_DATA_READ_IN : in std_logic; IPU_HDR_DATA_EMPTY_OUT : out std_logic; diff --git a/special/handler_ipu.vhd b/special/handler_ipu.vhd index 6ab7ebc..c13a509 100644 --- a/special/handler_ipu.vhd +++ b/special/handler_ipu.vhd @@ -15,14 +15,13 @@ entity handler_ipu is RESET : in std_logic; --From Data Handler - DAT_DATA : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); + DAT_DATA : in std_logic_vector(DATA_INTERFACE_NUMBER*36-1 downto 0); DAT_DATA_READ : out std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); DAT_DATA_EMPTY : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); DAT_HDR_DATA : in std_logic_vector(31 downto 0); DAT_HDR_DATA_READ : out std_logic; DAT_HDR_DATA_EMPTY : in std_logic; - --To IPU Channel IPU_NUMBER_IN : in std_logic_vector (15 downto 0); IPU_INFORMATION_IN : in std_logic_vector (7 downto 0); diff --git a/special/handler_lvl1.vhd b/special/handler_lvl1.vhd index 56e1291..7db3b5a 100644 --- a/special/handler_lvl1.vhd +++ b/special/handler_lvl1.vhd @@ -7,37 +7,38 @@ use work.trb_net_std.all; use work.trb_net_components.all; -entity lvl1_handler is +entity handler_lvl1 is + generic( + DATA_INTERFACE_NUMBER : integer range 1 to 16 := 1 + ); port ( - RESET : in std_logic; - CLOCK : in std_logic; + RESET : in std_logic; + CLOCK : in std_logic; --Timing Trigger - LVL1_TIMING_TRG_IN : in std_logic; + LVL1_TIMING_TRG_IN : in std_logic; --LVL1_handler connection - LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); - LVL1_TRG_RECEIVED_IN : in std_logic; - LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); - LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); - LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0); - LVL1_ERROR_PATTERN_OUT : out std_logic_vector(31 downto 0); - LVL1_TRG_RELEASE_OUT : out std_logic := '0'; - LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); + LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); + LVL1_TRG_RECEIVED_IN : in std_logic; + LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); + LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); + LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0); + LVL1_ERROR_PATTERN_OUT : out std_logic_vector(31 downto 0); + LVL1_TRG_RELEASE_OUT : out std_logic := '0'; + LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); --FEE logic / Data Handler - FEE_TIMING_TRIGGER_OUT : out std_logic; --timing trigger (registered) - FEE_TRG_RECEIVED_OUT : out std_logic; --TRG Info valid & FEE busy - FEE_TRG_TYPE_OUT : out std_logic_vector(3 downto 0); --trigger type - FEE_TRG_INFO_OUT : out std_logic_vector(23 downto 0); --further trigger details - FEE_TRG_CODE_OUT : out std_logic_vector(7 downto 0); --further trigger details - FEE_TRG_NUMBER_OUT : out std_logic_vector(15 downto 0); --trigger number - FEE_BUSY_IN : in std_logic; --FEE busy - FEE_BUFFER_WARN_IN : in std_logic; --some fifos (if any) might be full soon - FEE_TRG_STATUSBITS_IN : in std_logic_vector(31 downto 0); - - DAT_DATA_ALMOST_FULL_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); - DAT_DATA_STATUSBITS_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); + FEE_TIMING_TRIGGER_OUT : out std_logic; --timing trigger (registered) + FEE_TRG_RECEIVED_OUT : out std_logic; --TRG Info valid & FEE busy + FEE_TRG_TYPE_OUT : out std_logic_vector(3 downto 0); --trigger type + FEE_TRG_INFO_OUT : out std_logic_vector(23 downto 0); --further trigger details + FEE_TRG_CODE_OUT : out std_logic_vector(7 downto 0); --further trigger details + FEE_TRG_NUMBER_OUT : out std_logic_vector(15 downto 0); --trigger number + FEE_BUSY_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); + FEE_TRG_STATUSBITS_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); + DAT_TRG_STATUSBITS_IN : in std_logic_vector(31 downto 0); + DAT_TRG_RELEASE_IN : in std_logic; --Debug - DEBUG_OUT : out std_logic_vector (15 downto 0) + DEBUG_OUT : out std_logic_vector (15 downto 0) ); end entity; \ No newline at end of file diff --git a/special/handler_trigger_and_data.vhd b/special/handler_trigger_and_data.vhd index 4f42f86..544a5ad 100644 --- a/special/handler_trigger_and_data.vhd +++ b/special/handler_trigger_and_data.vhd @@ -52,16 +52,14 @@ entity handler_trigger_and_data is FEE_TRG_INFO_OUT : out std_logic_vector(23 downto 0); --further trigger details FEE_TRG_CODE_OUT : out std_logic_vector(7 downto 0); --further trigger details FEE_TRG_NUMBER_OUT : out std_logic_vector(15 downto 0); --trigger number - FEE_BUSY_IN : in std_logic; --FEE busy - FEE_BUFFER_WARN_IN : in std_logic; --some fifos (if any) might be full soon - FEE_TRG_STATUSBITS_IN : in std_logic_vector(31 downto 0); + FEE_TRG_RELEASE_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); + FEE_TRG_STATUSBITS_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); --Data Input from FEE FEE_DATA_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); FEE_DATA_WRITE_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); FEE_DATA_FINISHED_IN : in std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); FEE_DATA_ALMOST_FULL_OUT : out std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); - FEE_DATA_STATUSBITS_IN : in std_logic_vector(DATA_INTERFACE_NUMBER*32-1 downto 0); --Debug DEBUG_LVL1_HANDLER_OUT : out std_logic_vector(31 downto 0); @@ -77,9 +75,108 @@ end entity; architecture handler_trigger_and_data_arch of handler_trigger_and_data is -begin + signal fee_timing_trigger : std_logic; + signal fee_trg_received : std_logic; + signal fee_trg_type : std_logic_vector(3 downto 0); + signal fee_trg_info : std_logic_vector(23 downto 0); + signal fee_trg_code : std_logic_vector(7 downto 0); + signal fee_trg_number : std_logic_vector(15 downto 0); + signal fee_release : std_logic; + signal fee_trg_statusbits : std_logic_vector(31 downto 0); + signal dat_almost_full : std_logic; + signal dat_statusbits : std_logic_vector(31 downto 0); + + signal dat_buffer_warn : std_logic; + signal dat_buffer_full : std_logic; + signal dat_lvl1_statusbits : std_logic_vector(31 downto 0); + signal ipu_data : std_logic_vector(36*DATA_INTERFACE_NUMBER-1 downto 0); + signal ipu_data_read : std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); + signal ipu_data_empty : std_logic_vector(DATA_INTERFACE_NUMBER-1 downto 0); + signal ipu_data_length : std_logic_vector(16*DATA_INTERFACE_NUMBER-1 downto 0); + signal ipu_header : std_logic_vector(31 downto 0); + signal ipu_header_empty : std_logic; + signal ipu_header_read : std_logic; + +begin + THE_LVL1_HANDLER : handler_lvl1 + port map( + RESET => RESET, + CLOCK => CLOCK, + --Timing Trigger + LVL1_TIMING_TRG_IN => LVL1_TIMING_TRG_IN, + --LVL1_handler connection + LVL1_TRG_TYPE_IN => LVL1_TRG_TYPE_IN, + LVL1_TRG_RECEIVED_IN => LVL1_TRG_RECEIVED_IN, + LVL1_TRG_NUMBER_IN => LVL1_TRG_NUMBER_IN, + LVL1_TRG_CODE_IN => LVL1_TRG_CODE_IN, + LVL1_TRG_INFORMATION_IN => LVL1_TRG_INFORMATION_IN, + LVL1_ERROR_PATTERN_OUT => LVL1_ERROR_PATTERN_OUT, + LVL1_TRG_RELEASE_OUT => LVL1_TRG_RELEASE_OUT, + LVL1_INT_TRG_NUMBER_IN => LVL1_INT_TRG_NUMBER_IN, + + --FEE logic / Data Handler + FEE_TIMING_TRIGGER_OUT => fee_timing_trigger, + FEE_TRG_RECEIVED_OUT => fee_trg_received, + FEE_TRG_TYPE_OUT => fee_trg_type, + FEE_TRG_INFO_OUT => fee_trg_info, + FEE_TRG_CODE_OUT => fee_trg_code, + FEE_TRG_NUMBER_OUT => fee_trg_number, + FEE_BUSY_IN => fee_busy, + FEE_BUFFER_WARN_IN => fee_buffer_warn, + FEE_TRG_STATUSBITS_IN => fee_trg_statusbits, + + DAT_ALMOST_FULL_OUT => dat_almost_full, + DAT_STATUSBITS_IN => dat_statusbits, + + --Debug + DEBUG_OUT => DEBUG_LVL1_HANDLER_OUT + ); + + THE_DATA_HANDLER : handler_data + generic map( + DATA_INTERFACE_NUMBER => DATA_INTERFACE_NUMBER, + DATA_BUFFER_DEPTH => DATA_BUFFER_DEPTH, + DATA_BUFFER_FULL_THRESH => DATA_BUFFER_FULL_THRESH, + HEADER_BUFFER_DEPTH => HEADER_BUFFER_DEPTH, + HEADER_BUFFER_FULL_THRESH => HEADER_BUFFER_FULL_THRESH + ) + port map( + CLOCK => CLOCK, + RESET => RESET, + + --From LVL1 Handler + LVL1_TRG_RECEIVED_IN => fee_trigger_received, + LVL1_TRG_TYPE_IN => fee_trg_type, + LVL1_TRG_INFO_IN => fee_trg_info, + LVL1_TRG_NUMBER_IN => fee_trg_number, + LVL1_BUFFER_WARN_OUT => dat_buffer_warn, + LVL1_BUFFER_FULL_OUT => dat_buffer_full, + LVL1_STATUSBITS_OUT => dat_lvl1_statusbits, + + --From FEE + FEE_DATA_IN => FEE_DATA_IN, + FEE_DATA_WRITE_IN => FEE_DATA_WRITE_IN, + FEE_DATA_FINISHED_IN => FEE_DATA_FINISHED_IN, + FEE_DATA_ALMOST_FULL_OUT => FEE_DATA_ALMOST_FULL_OUT, + + --To IPU Handler + IPU_DATA_OUT => ipu_data, + IPU_DATA_READ_IN => ipu_data_read, + IPU_DATA_EMPTY_OUT => ipu_data_empty, + IPU_DATA_LENGTH => ipu_data_length, + IPU_HDR_DATA_OUT => ipu_header, + IPU_HDR_DATA_READ_IN => ipu_header_read, + IPU_HDR_DATA_EMPTY_OUT => ipu_header_empty, + + --Debug + DEBUG_OUT => DEBUG_DATA_HANDLER_OUT + ); + +-- combine LVL1 fee statusbits +-- combine FEE Busy Release + end architecture; \ No newline at end of file diff --git a/special/slv_register.vhd b/special/slv_register.vhd index 0681f39..763550b 100644 --- a/special/slv_register.vhd +++ b/special/slv_register.vhd @@ -1,177 +1,177 @@ -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 -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'; -- added 23022009 - elsif( (reg_busy = '1') and (slv_write_in = '1') ) then - NEXT_STATE <= WR_BSY; - slv_busy_x <= '1'; -- added 23022009 - 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 <= RESET_VALUE; - 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 <= reg_data_in; - 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; - ---------------------------------------------------------- --- signals to backend -- ---------------------------------------------------------- - -reg_data_out <= reg_slv_data_in; - -end Behavioral; +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 +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'; -- added 23022009 + elsif( (reg_busy = '1') and (slv_write_in = '1') ) then + NEXT_STATE <= WR_BSY; + slv_busy_x <= '1'; -- added 23022009 + 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 <= RESET_VALUE; + 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 <= reg_data_in; + 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; + +--------------------------------------------------------- +-- signals to backend -- +--------------------------------------------------------- + +reg_data_out <= reg_slv_data_in; + +end Behavioral; diff --git a/special/spi_master.vhd b/special/spi_master.vhd index aa2519b..683007c 100755 --- a/special/spi_master.vhd +++ b/special/spi_master.vhd @@ -1,256 +1,256 @@ -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; - -entity spi_master is - port( - CLK_IN : in std_logic; - RESET_IN : in std_logic; - -- Slave bus - BUS_READ_IN : in std_logic; - BUS_WRITE_IN : in std_logic; - BUS_BUSY_OUT : out std_logic; - BUS_ACK_OUT : out std_logic; - BUS_ADDR_IN : in std_logic_vector(0 downto 0); - BUS_DATA_IN : in std_logic_vector(31 downto 0); - BUS_DATA_OUT : out std_logic_vector(31 downto 0); - -- SPI connections - SPI_CS_OUT : out std_logic; - SPI_SDI_IN : in std_logic; - SPI_SDO_OUT : out std_logic; - SPI_SCK_OUT : out std_logic; - -- BRAM for read/write data - BRAM_A_OUT : out std_logic_vector(7 downto 0); - BRAM_WR_D_IN : in std_logic_vector(7 downto 0); - BRAM_RD_D_OUT : out std_logic_vector(7 downto 0); - BRAM_WE_OUT : out std_logic; - -- Status lines - STAT : out std_logic_vector(31 downto 0) -- DEBUG - ); -end entity; - -architecture Behavioral of spi_master is - -- Placer Directives - attribute HGROUP : string; - -- for whole architecture - attribute HGROUP of Behavioral : architecture is "SPI_group"; - --- Signals - type STATES is (SLEEP,RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); - signal CURRENT_STATE, NEXT_STATE: STATES; - - signal status_data : std_logic_vector(31 downto 0); - signal spi_busy : std_logic; - - signal reg_ctrl_data : std_logic_vector(31 downto 0); -- CMD, ADH, ADM, ADL - signal reg_status_data : std_logic_vector(31 downto 0); -- MAX - - signal reg_bus_data_out : std_logic_vector(31 downto 0); -- readback - - signal spi_bsm : std_logic_vector(7 downto 0); - signal spi_debug : std_logic_vector(31 downto 0); - - signal spi_start_x : std_logic; - signal spi_start : std_logic; - - -- State machine signals - signal bus_busy_x : std_logic; - signal bus_busy : std_logic; - signal bus_ack_x : std_logic; - signal bus_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; - -begin - ---------------------------------------------------------- --- SPI master -- ---------------------------------------------------------- - -THE_SPI_SLIM: spi_slim -port map( - SYSCLK => clk_in, - RESET => reset_in, - -- Command interface - START_IN => spi_start, -- not really nice, but should work - BUSY_OUT => spi_busy, - CMD_IN => reg_ctrl_data(31 downto 24), - ADH_IN => reg_ctrl_data(23 downto 16), - ADM_IN => reg_ctrl_data(15 downto 8), - ADL_IN => reg_ctrl_data(7 downto 0), - MAX_IN => reg_status_data(31 downto 24), - TXDATA_IN => bram_wr_d_in, - TX_RD_OUT => open, -- not needed - RXDATA_OUT => bram_rd_d_out, - RX_WR_OUT => bram_we_out, - TX_RX_A_OUT => bram_a_out, - -- SPI interface - SPI_SCK_OUT => spi_sck_out, - SPI_CS_OUT => spi_cs_out, - SPI_SDI_IN => spi_sdi_in, - SPI_SDO_OUT => spi_sdo_out, - -- DEBUG - CLK_EN_OUT => open, -- not needed - BSM_OUT => spi_bsm, - DEBUG_OUT => spi_debug --open -- BUG -); - ---------------------------------------------------------- --- Statemachine -- ---------------------------------------------------------- -STATE_MEM: process( clk_in ) -begin - if( rising_edge(clk_in) ) then - if( reset_in = '1' ) then - CURRENT_STATE <= SLEEP; - bus_busy <= '0'; - bus_ack <= '0'; - store_wr <= '0'; - store_rd <= '0'; - else - CURRENT_STATE <= NEXT_STATE; - bus_busy <= bus_busy_x; - bus_ack <= bus_ack_x; - store_wr <= store_wr_x; - store_rd <= store_rd_x; - end if; - end if; -end process STATE_MEM; - -TRANSFORM: process(CURRENT_STATE, bus_read_in, bus_write_in, spi_busy, bus_addr_in ) -begin - NEXT_STATE <= SLEEP; - bus_busy_x <= '0'; - bus_ack_x <= '0'; - store_wr_x <= '0'; - store_rd_x <= '0'; - case CURRENT_STATE is - when SLEEP => - if ( (spi_busy = '0') and (bus_read_in = '1') ) then - NEXT_STATE <= RD_RDY; - store_rd_x <= '1'; - elsif( (spi_busy = '0') and (bus_write_in = '1') ) then - NEXT_STATE <= WR_RDY; - store_wr_x <= '1'; - elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_read_in = '1') ) then - NEXT_STATE <= RD_BSY; -- CMD register is busy protected - bus_busy_x <= '1'; - elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_write_in = '1') ) then - NEXT_STATE <= WR_BSY; -- CMD register is busy protected - bus_busy_x <= '1'; - elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_read_in = '1') ) then - NEXT_STATE <= RD_RDY; -- STATUS register is not - store_rd_x <= '1'; - elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_write_in = '1') ) then - NEXT_STATE <= WR_RDY; -- STATUS register is not - store_wr_x <= '1'; - else - NEXT_STATE <= SLEEP; - end if; - when RD_RDY => - NEXT_STATE <= RD_ACK; - bus_ack_x <= '1'; - when WR_RDY => - NEXT_STATE <= WR_ACK; - bus_ack_x <= '1'; - when RD_ACK => - if( bus_read_in = '0' ) then - NEXT_STATE <= DONE; - else - NEXT_STATE <= RD_ACK; - bus_ack_x <= '1'; - end if; - when WR_ACK => - if( bus_write_in = '0' ) then - NEXT_STATE <= DONE; - else - NEXT_STATE <= WR_ACK; - bus_ack_x <= '1'; - end if; - when RD_BSY => - if( bus_read_in = '0' ) then - NEXT_STATE <= DONE; - else - NEXT_STATE <= RD_BSY; - bus_busy_x <= '1'; - end if; - when WR_BSY => - if( bus_write_in = '0' ) then - NEXT_STATE <= DONE; - else - NEXT_STATE <= WR_BSY; - bus_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_ctrl_data <= (others => '0'); - reg_status_data <= (others => '0'); - spi_start <= '0'; - elsif( (store_wr = '1') and (bus_addr_in(0) = '0') ) then - reg_ctrl_data <= bus_data_in; - spi_start <= spi_start_x; - elsif( (store_wr = '1') and (bus_addr_in(0) = '1') ) then - reg_status_data <= bus_data_in; - spi_start <= spi_start_x; - else - spi_start <= spi_start_x; - end if; - end if; - end process THE_WRITE_REG_PROC; - -spi_start_x <= '1' when ( (store_wr = '1') and (bus_addr_in(0) = '0') ) else '0'; - --- register read -THE_READ_REG_PROC: process( clk_in ) - begin - if( rising_edge(clk_in) ) then - if ( reset_in = '1' ) then - reg_bus_data_out <= (others => '0'); - elsif( (store_rd = '1') and (bus_addr_in(0) = '0') ) then - reg_bus_data_out <= reg_ctrl_data; - elsif( (store_rd = '1') and (bus_addr_in(0) = '1') ) then - reg_bus_data_out(31 downto 24) <= reg_status_data(31 downto 24); - reg_bus_data_out(23 downto 16) <= x"00"; - reg_bus_data_out(15 downto 8) <= x"00"; - reg_bus_data_out(7 downto 0) <= spi_bsm; - end if; - end if; - end process THE_READ_REG_PROC; - --- debug signals -status_data(31 downto 24) <= spi_bsm; -status_data(23) <= spi_start; -status_data(22 downto 0) <= (others => '0'); - --- output signals -bus_ack_out <= bus_ack; -bus_busy_out <= bus_busy; -bus_data_out <= reg_bus_data_out; -stat(31 downto 3) <= spi_debug(31 downto 3); --status_data; -stat(2) <= spi_start; -stat(1) <= bus_write_in; -stat(0) <= bus_read_in; - -end Behavioral; +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; + +entity spi_master is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + -- Slave bus + BUS_READ_IN : in std_logic; + BUS_WRITE_IN : in std_logic; + BUS_BUSY_OUT : out std_logic; + BUS_ACK_OUT : out std_logic; + BUS_ADDR_IN : in std_logic_vector(0 downto 0); + BUS_DATA_IN : in std_logic_vector(31 downto 0); + BUS_DATA_OUT : out std_logic_vector(31 downto 0); + -- SPI connections + SPI_CS_OUT : out std_logic; + SPI_SDI_IN : in std_logic; + SPI_SDO_OUT : out std_logic; + SPI_SCK_OUT : out std_logic; + -- BRAM for read/write data + BRAM_A_OUT : out std_logic_vector(7 downto 0); + BRAM_WR_D_IN : in std_logic_vector(7 downto 0); + BRAM_RD_D_OUT : out std_logic_vector(7 downto 0); + BRAM_WE_OUT : out std_logic; + -- Status lines + STAT : out std_logic_vector(31 downto 0) -- DEBUG + ); +end entity; + +architecture Behavioral of spi_master is + -- Placer Directives + attribute HGROUP : string; + -- for whole architecture + attribute HGROUP of Behavioral : architecture is "SPI_group"; + +-- Signals + type STATES is (SLEEP,RD_BSY,WR_BSY,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); + signal CURRENT_STATE, NEXT_STATE: STATES; + + signal status_data : std_logic_vector(31 downto 0); + signal spi_busy : std_logic; + + signal reg_ctrl_data : std_logic_vector(31 downto 0); -- CMD, ADH, ADM, ADL + signal reg_status_data : std_logic_vector(31 downto 0); -- MAX + + signal reg_bus_data_out : std_logic_vector(31 downto 0); -- readback + + signal spi_bsm : std_logic_vector(7 downto 0); + signal spi_debug : std_logic_vector(31 downto 0); + + signal spi_start_x : std_logic; + signal spi_start : std_logic; + + -- State machine signals + signal bus_busy_x : std_logic; + signal bus_busy : std_logic; + signal bus_ack_x : std_logic; + signal bus_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; + +begin + +--------------------------------------------------------- +-- SPI master -- +--------------------------------------------------------- + +THE_SPI_SLIM: spi_slim +port map( + SYSCLK => clk_in, + RESET => reset_in, + -- Command interface + START_IN => spi_start, -- not really nice, but should work + BUSY_OUT => spi_busy, + CMD_IN => reg_ctrl_data(31 downto 24), + ADH_IN => reg_ctrl_data(23 downto 16), + ADM_IN => reg_ctrl_data(15 downto 8), + ADL_IN => reg_ctrl_data(7 downto 0), + MAX_IN => reg_status_data(31 downto 24), + TXDATA_IN => bram_wr_d_in, + TX_RD_OUT => open, -- not needed + RXDATA_OUT => bram_rd_d_out, + RX_WR_OUT => bram_we_out, + TX_RX_A_OUT => bram_a_out, + -- SPI interface + SPI_SCK_OUT => spi_sck_out, + SPI_CS_OUT => spi_cs_out, + SPI_SDI_IN => spi_sdi_in, + SPI_SDO_OUT => spi_sdo_out, + -- DEBUG + CLK_EN_OUT => open, -- not needed + BSM_OUT => spi_bsm, + DEBUG_OUT => spi_debug --open -- BUG +); + +--------------------------------------------------------- +-- Statemachine -- +--------------------------------------------------------- +STATE_MEM: process( clk_in ) +begin + if( rising_edge(clk_in) ) then + if( reset_in = '1' ) then + CURRENT_STATE <= SLEEP; + bus_busy <= '0'; + bus_ack <= '0'; + store_wr <= '0'; + store_rd <= '0'; + else + CURRENT_STATE <= NEXT_STATE; + bus_busy <= bus_busy_x; + bus_ack <= bus_ack_x; + store_wr <= store_wr_x; + store_rd <= store_rd_x; + end if; + end if; +end process STATE_MEM; + +TRANSFORM: process(CURRENT_STATE, bus_read_in, bus_write_in, spi_busy, bus_addr_in ) +begin + NEXT_STATE <= SLEEP; + bus_busy_x <= '0'; + bus_ack_x <= '0'; + store_wr_x <= '0'; + store_rd_x <= '0'; + case CURRENT_STATE is + when SLEEP => + if ( (spi_busy = '0') and (bus_read_in = '1') ) then + NEXT_STATE <= RD_RDY; + store_rd_x <= '1'; + elsif( (spi_busy = '0') and (bus_write_in = '1') ) then + NEXT_STATE <= WR_RDY; + store_wr_x <= '1'; + elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_read_in = '1') ) then + NEXT_STATE <= RD_BSY; -- CMD register is busy protected + bus_busy_x <= '1'; + elsif( (bus_addr_in(0) = '0') and (spi_busy = '1') and (bus_write_in = '1') ) then + NEXT_STATE <= WR_BSY; -- CMD register is busy protected + bus_busy_x <= '1'; + elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_read_in = '1') ) then + NEXT_STATE <= RD_RDY; -- STATUS register is not + store_rd_x <= '1'; + elsif( (bus_addr_in(0) = '1') and (spi_busy = '1') and (bus_write_in = '1') ) then + NEXT_STATE <= WR_RDY; -- STATUS register is not + store_wr_x <= '1'; + else + NEXT_STATE <= SLEEP; + end if; + when RD_RDY => + NEXT_STATE <= RD_ACK; + bus_ack_x <= '1'; + when WR_RDY => + NEXT_STATE <= WR_ACK; + bus_ack_x <= '1'; + when RD_ACK => + if( bus_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_ACK; + bus_ack_x <= '1'; + end if; + when WR_ACK => + if( bus_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_ACK; + bus_ack_x <= '1'; + end if; + when RD_BSY => + if( bus_read_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= RD_BSY; + bus_busy_x <= '1'; + end if; + when WR_BSY => + if( bus_write_in = '0' ) then + NEXT_STATE <= DONE; + else + NEXT_STATE <= WR_BSY; + bus_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_ctrl_data <= (others => '0'); + reg_status_data <= (others => '0'); + spi_start <= '0'; + elsif( (store_wr = '1') and (bus_addr_in(0) = '0') ) then + reg_ctrl_data <= bus_data_in; + spi_start <= spi_start_x; + elsif( (store_wr = '1') and (bus_addr_in(0) = '1') ) then + reg_status_data <= bus_data_in; + spi_start <= spi_start_x; + else + spi_start <= spi_start_x; + end if; + end if; + end process THE_WRITE_REG_PROC; + +spi_start_x <= '1' when ( (store_wr = '1') and (bus_addr_in(0) = '0') ) else '0'; + +-- register read +THE_READ_REG_PROC: process( clk_in ) + begin + if( rising_edge(clk_in) ) then + if ( reset_in = '1' ) then + reg_bus_data_out <= (others => '0'); + elsif( (store_rd = '1') and (bus_addr_in(0) = '0') ) then + reg_bus_data_out <= reg_ctrl_data; + elsif( (store_rd = '1') and (bus_addr_in(0) = '1') ) then + reg_bus_data_out(31 downto 24) <= reg_status_data(31 downto 24); + reg_bus_data_out(23 downto 16) <= x"00"; + reg_bus_data_out(15 downto 8) <= x"00"; + reg_bus_data_out(7 downto 0) <= spi_bsm; + end if; + end if; + end process THE_READ_REG_PROC; + +-- debug signals +status_data(31 downto 24) <= spi_bsm; +status_data(23) <= spi_start; +status_data(22 downto 0) <= (others => '0'); + +-- output signals +bus_ack_out <= bus_ack; +bus_busy_out <= bus_busy; +bus_data_out <= reg_bus_data_out; +stat(31 downto 3) <= spi_debug(31 downto 3); --status_data; +stat(2) <= spi_start; +stat(1) <= bus_write_in; +stat(0) <= bus_read_in; + +end Behavioral; -- 2.43.0