diff --git a/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd b/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..73bba017275260d473aac051ff3f08676f7f1fca --- /dev/null +++ b/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd @@ -0,0 +1,837 @@ +--! @file EB_2_wb_converter.vhd +--! @brief EtherBone logic core +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +--! Additional library +library work; +--! Additional packages +use work.EB_HDR_PKG.all; +use work.wb32_package.all; + +entity eb_2_wb_converter is +port( + clk_i : in std_logic; --! System Clk + nRst_i : in std_logic; --! active low sync reset + + --Eth MAC WB Streaming signals + EB_RX_i : in wb32_slave_in; --! Streaming wishbone(record) sink from RX transport protocol block + EB_RX_o : out wb32_slave_out; --! Streaming WB sink flow control to RX transport protocol block + + EB_TX_i : in wb32_master_in; --! Streaming WB src flow control from TX transport protocol block + EB_TX_o : out wb32_master_out; --! Streaming WB src to TX transport protocol block + + byte_count_rx_i : in std_logic_vector(15 downto 0); --! Payload byte length from RX transport protocol block + + --config signals + config_master_i : in wb32_master_in; --! WB V4 interface to WB interconnect/device(s) + config_master_o : out wb32_master_out; --! WB V4 interface to WB interconnect/device(s) + + + + --WB IC signals + WB_master_i : in wb32_master_in; --! WB V4 interface to WB interconnect/device(s) + WB_master_o : out wb32_master_out --! WB V4 interface to WB interconnect/device(s) + + + +); +end eb_2_wb_converter; + +architecture behavioral of eb_2_wb_converter is + +--Signals +------------------------------------------------------------------------------------------ +--State Machines +------------------------------------------------------------------------------------------ +constant c_width_int : integer := 24; +type t_state_RX is (IDLE, EB_HDR_REC, EB_HDR_PROC, EB_HDR_PROBE_ID, CYC_HDR_REC, CYC_HDR_READ_PROC, CYC_HDR_READ_GET_ADR, WB_READ_RDY, WB_READ, CYC_HDR_WRITE_PROC, CYC_HDR_WRITE_GET_ADR, WB_WRITE_RDY, WB_WRITE, CYC_DONE, EB_DONE, ERROR); +type t_state_TX is (IDLE, EB_HDR_INIT, EB_HDR_PROBE_ID, EB_HDR_PROBE_WAIT, PACKET_HDR_SEND, EB_HDR_SEND, RDY, CYC_HDR_INIT, CYC_HDR_SEND, BASE_WRITE_ADR_SEND, DATA_SEND, ZERO_PAD_WRITE, ZERO_PAD_WAIT, ERROR); + + + +signal s_state_RX : t_state_RX := IDLE; +signal s_state_TX : t_state_TX := IDLE; + +constant test : std_logic_vector(31 downto 0) := (others => '0'); + +------------------------------------------------------------------------------------------ +--Wishbone Interfaces +------------------------------------------------------------------------------------------ +signal s_WB_master_i : wb32_master_in; +signal s_WB_master_o : wb32_master_out; + +signal s_WB_STB : std_logic; +signal s_WB_ADR : std_logic_vector(WB_master_o.ADR'left downto 0); +signal s_WB_CYC : std_logic; +signal s_WB_WE : std_logic; +signal s_TX_STROBED : std_logic; + +signal s_WB_addr_inc : unsigned(c_EB_ADDR_SIZE_n-1 downto 0); +signal s_WB_addr_cnt : unsigned(c_EB_ADDR_SIZE_n-1 downto 0); + +------------------------------------------------------------------------------------------ +-- Byte/Pulse Counters +------------------------------------------------------------------------------------------ +signal s_WB_ACK_cnt_big : unsigned(8 downto 0); +alias a_WB_ACK_cnt : unsigned(7 downto 0) is s_WB_ACK_cnt_big(7 downto 0); +alias a_WB_ACK_cnt_err : unsigned(0 downto 0) is s_WB_ACK_cnt_big(8 downto 8); + +signal s_EB_probe_wait_cnt : unsigned(3 downto 0); +signal s_EB_TX_zeropad_cnt : unsigned(7 downto 0); +signal s_EB_RX_byte_cnt : unsigned(15 downto 0); +signal s_EB_TX_byte_cnt : unsigned(15 downto 0); + +signal debug_stb_cnt : natural := 0; +signal debug_byte_diff : unsigned(15 downto 0); +signal debug_diff : std_logic; +signal debugsum : unsigned(15 downto 0); + +------------------------------------------------------------------------------------------ +--Config and Status Regs +------------------------------------------------------------------------------------------ +signal s_WB_Config_o : wb32_slave_out; +signal s_WB_Config_i : wb32_slave_in; +signal s_ADR_CONFIG : std_logic; + +signal s_status_en : std_logic; +signal s_status_clr : std_logic; + +------------------------------------------------------------------------------------------ +--Etherbone Signals +------------------------------------------------------------------------------------------ +signal s_EB_RX_ACK : std_logic; +signal s_EB_RX_STALL : std_logic; +signal s_EB_TX_STB : std_logic; +signal s_packet_reception_complete : std_logic; + +signal sink_valid : std_logic; + +------------------------------------------------------------------------------------------ +--Etherbone Registers +------------------------------------------------------------------------------------------ +constant c_WB_WORDSIZE : natural := 32; +constant c_EB_HDR_LEN : unsigned(3 downto 0):= x"0"; +signal s_EB_TX_base_wr_adr : std_logic_vector(31 downto 0); +signal s_EB_packet_length : unsigned(15 downto 0); + +signal s_EB_RX_HDR : EB_HDR; +signal s_EB_RX_CUR_CYCLE : EB_CYC; +signal s_EB_TX_HDR : EB_HDR; +signal s_EB_TX_CUR_CYCLE : EB_CYC; + +------------------------------------------------------------------------------------------ +--Etherbone FIFO Buffers +------------------------------------------------------------------------------------------ +signal s_tx_fifo_am_full : std_logic; +signal s_tx_fifo_full : std_logic; +signal s_tx_fifo_am_empty : std_logic; +signal s_tx_fifo_empty : std_logic; +signal s_tx_fifo_data : std_logic_vector(31 downto 0); +signal s_tx_fifo_rd : std_logic; +signal s_tx_fifo_clr : std_logic; +signal s_tx_fifo_we : std_logic; +signal s_tx_fifo_gauge : std_logic_vector(3 downto 0); + +signal s_rx_fifo_am_full : std_logic; +signal s_rx_fifo_full : std_logic; +signal s_rx_fifo_am_empty : std_logic; +signal s_rx_fifo_empty : std_logic; +signal s_rx_fifo_data : std_logic_vector(31 downto 0); +signal s_rx_fifo_q : std_logic_vector(31 downto 0); +signal s_rx_fifo_rd : std_logic; +signal s_rx_fifo_clr : std_logic; +signal s_rx_fifo_we : std_logic; +signal s_rx_fifo_gauge : std_logic_vector(3 downto 0); +------------------------------------------------------------------------------------------ + + +signal PROBE_ID : std_logic_vector(31 downto 0); + +constant WBM_Zero_o : wb32_master_out := (CYC => '0', + STB => '0', + ADR => (others => '0'), + SEL => (others => '0'), + WE => '0', + DAT => (others => '0')); + +constant WBS_Zero_o : wb32_slave_out := (ACK => '0', + ERR => '0', + RTY => '0', + STALL => '0', + DAT => (others => '0')); + +component alt_FIFO_am_full_flag IS + PORT + ( + clock : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (31 DOWNTO 0); + rdreq : IN STD_LOGIC ; + sclr : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + almost_empty : OUT STD_LOGIC ; + almost_full : OUT STD_LOGIC ; + empty : OUT STD_LOGIC ; + full : OUT STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + usedw : OUT STD_LOGIC_VECTOR (3 DOWNTO 0) + ); +end component alt_FIFO_am_full_flag; + +begin + +TX_FIFO : alt_FIFO_am_full_flag +port map( + clock => clk_i, + data => s_tx_fifo_data, + rdreq => s_tx_fifo_rd, + sclr => s_tx_fifo_clr, + wrreq => s_tx_fifo_we, + almost_empty => s_tx_fifo_am_empty, + almost_full => s_tx_fifo_am_full, + empty => s_tx_fifo_empty, + full => s_tx_fifo_full, + q => EB_TX_o.DAT, + usedw => s_tx_fifo_gauge + ); + +--strobe out as long as there is data left +EB_TX_o.STB <= NOT s_tx_fifo_empty; + +--read data from RX fifo as long as TX interface is free +s_tx_fifo_rd <= NOT EB_TX_i.STALL; + +--write in pending data as long as there is space left +s_tx_fifo_we <= s_EB_TX_STB AND NOT s_tx_fifo_full; + + RX_FIFO : alt_FIFO_am_full_flag +port map( + clock => clk_i, + data => EB_RX_i.DAT, + rdreq => s_rx_fifo_rd, + sclr => s_rx_fifo_clr, + wrreq => s_rx_fifo_we, + almost_empty => open, + almost_full => s_rx_fifo_am_full, + empty => s_rx_fifo_empty, + full => s_rx_fifo_full, + q => s_rx_fifo_q, + usedw => s_rx_fifo_gauge + ); + +--BUG: almost_empty flag is stuck after hitting empty repeatedly. +--create our own for now +s_rx_fifo_am_empty <= '1' when unsigned(s_rx_fifo_gauge) <= 1 + else '0'; + +--workaround to avoid creation of two drivers for the s_WB_master_o record +s_WB_master_o.DAT <= s_rx_fifo_q; +s_WB_master_o.STB <= s_WB_STB; + +--when reading, incoming rx data goes on the WB address lines +s_WB_master_o.ADR <= s_rx_fifo_q when s_state_RX = WB_READ + else s_WB_ADR; + +s_WB_master_o.CYC <= s_WB_CYC; +s_WB_master_o.WE <= s_WB_WE; +EB_RX_o.STALL <= s_rx_fifo_am_full; +EB_RX_o.ACK <= s_EB_RX_ACK; +EB_RX_o.ERR <= '0'; + +s_rx_fifo_we <= EB_RX_i.STB AND NOT (s_rx_fifo_am_full); -- OR s_packet_reception_complete); + + +--MUX lines: WB master / config space master +--------------------------------- +Mux_WB_Cfg_in : with s_ADR_CONFIG select +s_WB_master_i <= config_master_i when '1', + WB_master_i when others; + +-- select WB Master Port Out: Tie to ground / Signal s_WB_master_o +Mux_WB_out : with s_ADR_CONFIG select +WB_master_o <= WBM_Zero_o when '1', + s_WB_master_o when others; + +-- select WB Master Port Out: Tie to ground / Signal s_WB_master_o +Mux_Cfg_out : with s_ADR_CONFIG select +config_master_o <= s_WB_master_o when '1', + WBM_Zero_o when others; +----------------------------------- + + + + + +debug_diff <= '1' when debug_byte_diff > 0 else '0'; + +count_io : process(clk_i) +begin + if rising_edge(clk_i) then + + if (nRST_i = '0') then + s_EB_RX_byte_cnt <= (others => '0'); + s_EB_TX_byte_cnt <= (others => '0'); + s_WB_ACK_cnt_big <= (others => '0'); + else + + + --Counter: RX bytes received + if(s_state_RX = IDLE) then + s_EB_RX_byte_cnt <= (others => '0'); + else + if(s_rx_fifo_we = '1') then + s_EB_RX_byte_cnt <= s_EB_RX_byte_cnt + 4; + end if; + end if; + -- packet reception is not complete if min packet size not reached and < s_EB_packet_length + -- + if((s_EB_RX_byte_cnt < s_EB_packet_length) OR (s_EB_RX_byte_cnt < 16)) then + s_packet_reception_complete <= '0'; + else + s_packet_reception_complete <= '1'; + end if; + + --Counter: WB ACKs received + if(s_state_RX = IDLE) then + s_WB_ACK_cnt_big <= (others => '0'); + else + if(s_state_RX = CYC_HDR_WRITE_PROC) then + a_WB_ACK_cnt <= s_EB_RX_CUR_CYCLE.RD_CNT + s_EB_RX_CUR_CYCLE.WR_CNT; + elsif(s_WB_master_i.ACK = '1') then + a_WB_ACK_cnt <= a_WB_ACK_cnt -1; + end if; + end if; + + --Counter: WB ACKs received + if(s_state_RX = IDLE) then + debug_stb_cnt <= 0; + else + if(s_state_RX = CYC_HDR_WRITE_PROC) then + debug_stb_cnt <= 0; + elsif(s_WB_master_o.STB = '1') then + debug_stb_cnt <= debug_stb_cnt +1; + end if; + end if; + + --Counter: TX bytes sent + if(s_state_TX = IDLE) then + s_EB_TX_byte_cnt <= (others => '0'); + else + if(s_tx_fifo_we = '1') then + s_EB_TX_byte_cnt <= s_EB_TX_byte_cnt + 4; + end if; + end if; + + --Counter: Probewait + if(s_state_TX = EB_HDR_PROBE_ID) then + s_EB_probe_wait_cnt <= (others => '0'); + else + if(s_state_TX = EB_HDR_PROBE_WAIT) then + s_EB_probe_wait_cnt <= s_EB_probe_wait_cnt +1; + end if; + end if; + + + end if; + end if; +end process; + +p_state_transition: process(clk_i) +begin + if rising_edge(clk_i) then + + --========================================================================== + -- SYNC RESET +--========================================================================== + + if (nRST_i = '0') then + + s_state_TX <= IDLE; + s_state_RX <= IDLE; + + else + -- RX cycle line lowered before all words were transferred + if (s_EB_RX_byte_cnt < s_EB_packet_length + AND EB_RX_i.CYC = '0') then + report "EB: PACKET WAS ABORTED" severity note; + -- ERROR: -- RX cycle line lowered before all words were transferred + s_state_RX <= IDLE; + s_state_TX <= IDLE; + -- + elsif(s_EB_RX_byte_cnt > s_EB_packet_length AND NOT (s_EB_RX_byte_cnt < 16)) then + report "EB: PACKET TOO LONG" severity note; + s_state_RX <= IDLE; + s_state_TX <= IDLE; + else + + case s_state_RX is + when IDLE => if(s_rx_fifo_empty = '1') then + s_state_TX <= IDLE; + s_state_RX <= EB_HDR_REC; + report "EB: RDY" severity note; + end if; + + when EB_HDR_REC => if(EB_RX_i.CYC = '1' AND s_rx_fifo_empty = '0') then + s_state_RX <= EB_HDR_PROC; + end if; + + when EB_HDR_PROC => if( (s_EB_RX_HDR.EB_MAGIC /= c_EB_MAGIC_WORD) -- not EB + OR (s_EB_RX_HDR.VER /= c_EB_VER) -- wrong version + OR ((s_EB_RX_HDR.ADDR_SIZE AND c_MY_EB_ADDR_SIZE) = x"0") -- wrong size + OR ((s_EB_RX_HDR.PORT_SIZE AND c_MY_EB_PORT_SIZE)= x"0")) -- wrong size + then + s_state_RX <= ERROR; + report "EB: MALFORMED PACKET" severity note; + else + --eb hdr seems valid, prepare answering packet. Prefill RX buffer + if(unsigned(s_rx_fifo_gauge) > 3) then + s_state_RX <= CYC_HDR_REC; + s_state_TX <= EB_HDR_INIT; + else + report "EB: Waiting for buffer ..." severity note; + end if; + if(s_EB_RX_HDR.PROBE = '1') then -- no probe, prepare cycle reception + s_state_RX <= EB_HDR_PROBE_ID ; + s_state_TX <= EB_HDR_INIT; + end if; + end if; + + when EB_HDR_PROBE_ID => s_state_RX <= EB_DONE; + + when CYC_HDR_REC => if(s_rx_fifo_empty = '0') then + s_state_RX <= CYC_HDR_WRITE_PROC; + end if; + + when CYC_HDR_WRITE_PROC => if(s_EB_RX_CUR_CYCLE.WR_CNT > 0) then + s_state_RX <= CYC_HDR_WRITE_GET_ADR; + else + s_state_RX <= CYC_HDR_READ_PROC; + end if; + + + when CYC_HDR_WRITE_GET_ADR => if(s_rx_fifo_am_empty = '0') then + s_state_RX <= WB_WRITE_RDY; + end if; + + when WB_WRITE_RDY => if(s_state_TX = RDY) then + s_state_RX <= WB_WRITE; + s_state_TX <= ZERO_PAD_WRITE; + end if; + + when WB_WRITE => if(s_EB_RX_CUR_CYCLE.WR_CNT = 0 ) then --underflow of RX_cyc_wr_count + s_state_RX <= CYC_HDR_READ_PROC; + end if; + + when CYC_HDR_READ_PROC => if(s_state_TX = RDY) then + --are there reads to do? + + if(s_EB_RX_CUR_CYCLE.RD_CNT > 0) then + s_state_TX <= CYC_HDR_INIT; + s_state_RX <= CYC_HDR_READ_GET_ADR; + else + s_state_RX <= CYC_DONE; + end if; + + end if; + + when CYC_HDR_READ_GET_ADR => if(s_rx_fifo_am_empty = '0') then + s_state_RX <= WB_READ_RDY; + end if; + + when WB_READ_RDY => if(s_state_TX = RDY) then + s_state_RX <= WB_READ; + s_state_TX <= BASE_WRITE_ADR_SEND; + end if; + + when WB_READ => if(s_EB_RX_CUR_CYCLE.RD_CNT = 0) then + s_state_RX <= CYC_DONE; + end if; + + when CYC_DONE => if(a_WB_ACK_cnt = 0 AND s_tx_fifo_we = '0') then + if((s_EB_RX_byte_cnt < s_EB_packet_length) OR (s_EB_RX_byte_cnt = s_EB_packet_length AND s_rx_fifo_am_empty = '0')) then + s_state_RX <= CYC_HDR_REC; + else + --no more cycles to do, packet is done. reset FSMs + if(s_tx_fifo_empty = '1') then + s_state_RX <= EB_DONE; + s_state_TX <= IDLE; + end if; + end if; + elsif(a_WB_ACK_cnt_err = "1") then + s_state_RX <= ERROR; + end if; + + when EB_DONE => if(s_state_TX = IDLE OR s_state_TX = RDY) then -- 1. packet done, 2. probe done + s_state_RX <= IDLE; + s_state_TX <= IDLE; + end if; + + when ERROR => s_state_TX <= IDLE; + s_state_RX <= IDLE; + if((s_EB_RX_HDR.VER /= c_EB_VER) -- wrong version + OR (s_EB_RX_HDR.ADDR_SIZE /= c_MY_EB_ADDR_SIZE) -- wrong size + OR (s_EB_RX_HDR.PORT_SIZE /= c_MY_EB_PORT_SIZE)) then + s_state_TX <= ERROR; + end if; + + when others => s_state_RX <= IDLE; + end case; + + + case s_state_TX is + when IDLE => null; + + when RDY => null;--wait + + when EB_HDR_INIT => s_state_TX <= PACKET_HDR_SEND; + + when PACKET_HDR_SEND => s_state_TX <= EB_HDR_SEND; + + --TODO: padding to 64bit alignment + when EB_HDR_SEND => if(s_tx_fifo_full = '0') then + if(s_EB_RX_HDR.PROBE = '1') then + s_state_TX <= EB_HDR_PROBE_ID; + else + s_state_TX <= RDY; + end if; + end if; + + when EB_HDR_PROBE_ID => s_state_TX <= EB_HDR_PROBE_WAIT; + + + + + when EB_HDR_PROBE_WAIT => if(s_EB_probe_wait_cnt > 3 AND s_tx_fifo_empty = '1' ) then + s_state_TX <= IDLE; + end if; + + + + when CYC_HDR_INIT => s_state_TX <= CYC_HDR_SEND; + + when CYC_HDR_SEND => if(s_tx_fifo_full = '0') then + s_state_TX <= RDY; + end if; + + when BASE_WRITE_ADR_SEND => if(s_tx_fifo_full = '0') then + s_state_TX <= DATA_SEND; + end if; + + when DATA_SEND => --only write at the moment! + if(s_EB_TX_CUR_CYCLE.WR_CNT = 0) then + s_state_TX <= RDY; + end if; + + when ZERO_PAD_WRITE => if(s_EB_TX_zeropad_cnt = 0) then + s_state_TX <= RDY; + end if; + + when ZERO_PAD_WAIT => null; + + when others => s_state_TX <= IDLE; + end case; + + end if; + + end if; + end if; + +end process p_state_transition; + +p_state_output: process(clk_i) +begin + if rising_edge(clk_i) then + + --========================================================================== + -- SYNC RESET +--========================================================================== + + if (nRST_i = '0') then + + s_EB_TX_HDR <= init_EB_HDR; + PROBE_ID <= X"1337BEEF"; + s_EB_TX_CUR_CYCLE <= to_EB_CYC(test); + s_EB_TX_base_wr_adr<= (others => '0'); + s_EB_RX_CUR_CYCLE <= to_EB_CYC(test); + + s_EB_RX_ACK <= '0'; + + + EB_TX_o.CYC <= '0'; + + EB_TX_o.ADR <= (others => '0'); + EB_TX_o.SEL <= (others => '1'); + + EB_TX_o.WE <= '1'; + + s_EB_RX_STALL <= '0'; + + s_WB_addr_cnt <= (others => '0'); + s_EB_packet_length <= (others => '0'); + s_ADR_CONFIG <= '0'; + s_tx_fifo_clr <= '1'; + s_rx_fifo_clr <= '1'; + s_status_en <= '0'; + s_status_clr <= '0'; + + + s_WB_STB <= '0'; + s_WB_WE <= '0'; + s_WB_ADR <= (others => '0'); + + s_EB_TX_zeropad_cnt<= (others => '0'); + else + + + s_EB_RX_ACK <= s_rx_fifo_we; --EB_RX_i.STB AND NOT slave_RX_stream_STALL; + + + + s_rx_fifo_rd <= '0'; + s_WB_WE <= '0'; + s_WB_STB <= '0'; + s_EB_TX_STB <= '0'; + + s_status_en <= '0'; + s_status_clr <= '0'; + + s_tx_fifo_clr <= '0'; + s_rx_fifo_clr <= '0'; + + + + + case s_state_RX is + when IDLE => s_tx_fifo_clr <= '1'; + s_rx_fifo_clr <= '1'; + s_status_clr <= '1'; + + when EB_HDR_REC => if(EB_RX_i.CYC = '1' AND s_rx_fifo_empty = '0') then + s_EB_RX_HDR <= to_EB_HDR(s_rx_fifo_q); + s_EB_packet_length <= unsigned(byte_count_rx_i); + s_rx_fifo_rd <= '1'; + end if; + + when EB_HDR_PROC => null; + + + when EB_HDR_PROBE_ID => if(EB_RX_i.CYC = '1' AND s_rx_fifo_empty = '0') then + PROBE_ID <= s_rx_fifo_q; + s_rx_fifo_rd <= '1'; + end if; + + + when CYC_HDR_REC => if(s_rx_fifo_empty = '0') then + s_EB_RX_CUR_CYCLE <= TO_EB_CYC(s_rx_fifo_q); + s_rx_fifo_rd <= '1'; + end if; + + when CYC_HDR_WRITE_PROC => if(s_EB_RX_CUR_CYCLE.WR_CNT > 0) then + --setup word counters + s_ADR_CONFIG <= s_EB_RX_CUR_CYCLE.WCA_CFG; + end if; + + + when CYC_HDR_WRITE_GET_ADR => if(s_rx_fifo_am_empty = '0') then + s_WB_addr_cnt <= unsigned(s_rx_fifo_q); + s_rx_fifo_rd <= '1'; -- only stall RX if we got an adress, otherwise continue listening + end if; + + when WB_WRITE_RDY => if(s_state_TX = RDY) then + s_WB_CYC <= '1'; + -- only stall RX if we got an adress, otherwise continue listening + --s_WB_master_o.DAT <= s_rx_fifo_q; + if(s_EB_RX_CUR_CYCLE.RD_CNT > 0) then + s_EB_TX_zeropad_cnt <= s_EB_RX_CUR_CYCLE.WR_CNT+1; --wr start addr + else + s_EB_TX_zeropad_cnt <= s_EB_RX_CUR_CYCLE.WR_CNT+2; --wr start addr + header because read block is not called + end if; + end if; + + when WB_WRITE => s_status_en <= s_WB_master_i.ACK; + if(s_EB_RX_CUR_CYCLE.WR_CNT > 0 ) then --underflow of RX_cyc_wr_count + + s_WB_ADR <= std_logic_vector(s_WB_addr_cnt); + s_WB_WE <= '1'; + + -- case 1: elements 0 -> n-2 + -- case 2: n-1 + -- done to prevent buffer underrun + + if(s_rx_fifo_am_empty = '0') then + s_WB_STB <= '1'; + if(s_WB_master_i.STALL = '0') then + s_rx_fifo_rd <= '1'; + s_EB_RX_CUR_CYCLE.WR_CNT <= s_EB_RX_CUR_CYCLE.WR_CNT-1; + if(s_EB_RX_CUR_CYCLE.WR_FIFO = '0') then + s_WB_addr_cnt <= s_WB_addr_cnt + 4; + end if; + end if; + elsif(s_rx_fifo_empty = '0' AND (s_EB_RX_byte_cnt = s_EB_packet_length)) then + s_WB_STB <= '1'; + if(s_WB_master_i.STALL = '0') then + s_EB_RX_CUR_CYCLE.WR_CNT <= s_EB_RX_CUR_CYCLE.WR_CNT-1; + end if; + end if; + + end if; + + when CYC_HDR_READ_PROC => if(s_state_TX = RDY) then + --are there reads to do? + + if(s_EB_RX_CUR_CYCLE.RD_CNT > 0) then + --setup word counters + s_ADR_CONFIG <= s_EB_RX_CUR_CYCLE.RCA_CFG; + + end if; + + end if; + + when CYC_HDR_READ_GET_ADR => if(s_rx_fifo_am_empty = '0') then + --wait for ready from tx output + s_EB_TX_base_wr_adr <= s_rx_fifo_q; + s_rx_fifo_rd <= '1'; + end if; + + + when WB_READ_RDY => if(s_state_TX = RDY) then + s_WB_CYC <= '1'; + end if; + + when WB_READ => s_status_en <= s_WB_master_i.ACK; + if(s_state_TX = DATA_SEND AND s_EB_RX_CUR_CYCLE.RD_CNT > 0) then + + --s_WB_ADR <= s_rx_fifo_q; + --only go down to almost empty to keep pipeline filled + if((s_rx_fifo_am_empty = '0') ) then + if(s_tx_fifo_am_full = '0') then + s_WB_STB <= '1'; + if(s_WB_master_i.STALL = '0') then + s_rx_fifo_rd <= '1'; + s_EB_RX_CUR_CYCLE.RD_CNT <= s_EB_RX_CUR_CYCLE.RD_CNT-1; + end if; + end if; + else + --if these are the last bytes of the packet, empty pipeline. + if(s_rx_fifo_empty = '0' AND (s_EB_RX_byte_cnt = s_EB_packet_length)) then + if(s_tx_fifo_am_full = '0') then + s_WB_STB <= '1'; + if(s_WB_master_i.STALL = '0') then + s_EB_RX_CUR_CYCLE.RD_CNT <= s_EB_RX_CUR_CYCLE.RD_CNT-1; + end if; + end if; + + end if; + end if; + end if; + + when CYC_DONE => s_status_en <= s_WB_master_i.ACK; + if(a_WB_ACK_cnt = 0 AND s_tx_fifo_we = '0') then + --keep cycle line high if no drop requested + s_WB_CYC <= NOT s_EB_RX_CUR_CYCLE.DROP_CYC; + s_status_clr <= s_EB_RX_CUR_CYCLE.DROP_CYC; + end if; + + when EB_DONE => report "EB: PACKET COMPLETE" severity note; + --TODO: test multi packet mode + s_WB_CYC <= NOT s_EB_RX_CUR_CYCLE.DROP_CYC; + --make sure there is no running transfer before resetting FSMs, also do not start a new packet proc before cyc has been lowered + + when ERROR => report "EB: ERROR" severity warning; + s_WB_CYC <= '0'; + end case; + + + + + + + case s_state_TX is + when IDLE => EB_TX_o.CYC <= '0'; + + when RDY => null;--wait + + when EB_HDR_INIT => s_EB_TX_HDR <= init_EB_hdr; + s_EB_TX_HDR.PROBE_RES <= s_EB_RX_HDR.PROBE; + + + when PACKET_HDR_SEND => EB_TX_o.CYC <= '1'; + --using stall line for signalling the completion of Eth packet hdr + + --TODO: padding to 64bit alignment + when EB_HDR_SEND => s_EB_TX_STB <= '1'; + s_tx_fifo_data <= to_std_logic_vector(s_EB_TX_HDR); + + when EB_HDR_PROBE_ID => s_EB_TX_STB <= '1'; + s_tx_fifo_data <= PROBE_ID; + + + when CYC_HDR_INIT => s_EB_TX_CUR_CYCLE.WCA_CFG <= s_EB_RX_CUR_CYCLE.BCA_CFG; + s_EB_TX_CUR_CYCLE.RD_FIFO <= '0'; + s_EB_TX_CUR_CYCLE.RD_CNT <= (others => '0'); + s_EB_TX_CUR_CYCLE.WR_FIFO <= s_EB_RX_CUR_CYCLE.RD_FIFO; + s_EB_TX_CUR_CYCLE.WR_CNT <= s_EB_RX_CUR_CYCLE.RD_CNT; + + when CYC_HDR_SEND => s_tx_fifo_data <= TO_STD_LOGIC_VECTOR(s_EB_TX_CUR_CYCLE); + s_EB_TX_STB <= '1'; + + when BASE_WRITE_ADR_SEND => s_EB_TX_STB <= '1'; + s_tx_fifo_data <= s_EB_TX_base_wr_adr; + + when DATA_SEND => s_tx_fifo_data <= s_WB_master_i.DAT; + s_EB_TX_STB <= s_WB_master_i.ACK; + + if(s_WB_master_i.ACK = '1') then + s_EB_TX_CUR_CYCLE.WR_CNT <= s_EB_TX_CUR_CYCLE.WR_CNT-1; + end if; + + when ZERO_PAD_WRITE => s_tx_fifo_data <= (others => '0'); + if((s_tx_fifo_am_full = '0') AND (s_eb_tx_zeropad_cnt > 0)) then + --if(s_tx_fifo_we = '1') then + s_EB_TX_zeropad_cnt <= s_EB_TX_zeropad_cnt -1; + --end if; + s_EB_TX_STB <= '1'; + end if; + + when ZERO_PAD_WAIT => null; + + when others => null; + end case; + end if; + end if; + +end process p_state_output; + + + + + +end behavioral; diff --git a/hdl/EB_SPEC_Test/EB_CORE.vhd b/hdl/EB_SPEC_Test/EB_CORE.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6ce2a6b2cb258bc0cc8b1460ee660c8a239f5034 --- /dev/null +++ b/hdl/EB_SPEC_Test/EB_CORE.vhd @@ -0,0 +1,549 @@ +--! @file EB_CORE.vhd +--! @brief Top file for EtherBone core +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +--! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.EB_HDR_PKG.all; +--use work.EB_components_pkg.all; +use work.wb32_package.all; +use work.wb16_package.all; + + +entity EB_CORE is +generic(g_master_slave : STRING := "SLAVE"); +port +( + clk_i : in std_logic; --! clock input + nRst_i : in std_logic; + + -- slave RX streaming IF ------------------------------------- + snk_CYC_i : in std_logic; -- + snk_STB_i : in std_logic; -- + snk_DAT_i : in std_logic_vector(15 downto 0); -- + snk_sel_i : in std_logic_vector(1 downto 0); + snk_adr_i : in std_logic_vector(1 downto 0); + snk_WE_i : in std_logic; + snk_STALL_o : out std_logic; -- + snk_ERR_o : out std_logic; -- + snk_ACK_o : out std_logic; -- + -------------------------------------------------------------- + + -- master TX streaming IF ------------------------------------ + src_CYC_o : out std_logic; -- + src_STB_o : out std_logic; -- + src_WE_o : out std_logic; + src_DAT_o : out std_logic_vector(15 downto 0); -- + src_STALL_i : in std_logic; -- + src_ERR_i : in std_logic; -- + src_ACK_i : in std_logic; -- + src_adr_o : out std_logic_vector(1 downto 0); + + src_sel_o : out std_logic_vector(1 downto 0); + -------------------------------------------------------------- + debug_TX_TOL_o : out std_logic_vector(15 downto 0); + hex_switch_i : in std_logic_vector(3 downto 0); + + -- slave Cfg IF ---------------------------------------------- + cfg_slave_cyc_i : in std_logic; +cfg_slave_we_i : in std_logic; +cfg_slave_stb_i : in std_logic; +cfg_slave_sel_i : in std_logic_vector(3 downto 0); +cfg_slave_adr_i : in std_logic_vector(31 downto 0); +cfg_slave_dat_i : in std_logic_vector(31 downto 0); +cfg_slave_dat_o : out std_logic_vector(31 downto 0); +cfg_slave_stall_o : out std_logic; +cfg_slave_ack_o : out std_logic; +cfg_slave_err_o : out std_logic; + + -- master IC IF ---------------------------------------------- + master_cyc_o : out std_logic; + master_we_o : out std_logic; + master_stb_o : out std_logic; + master_sel_o : out std_logic_vector(3 downto 0); + master_adr_o : out std_logic_vector(31 downto 0); + master_dat_o : out std_logic_vector(31 downto 0); + master_dat_i : in std_logic_vector(31 downto 0); + master_stall_i : in std_logic; + master_ack_i : in std_logic + -------------------------------------------------------------- + +); +end EB_CORE; + + + + + + +architecture behavioral of EB_CORE is + +signal s_status_en : std_logic; +signal s_status_clr : std_logic; + + +signal DEBUG_sink1_valid : std_logic; +signal DEBUG_sink23_valid : std_logic; + +signal DEBUG_WB_master_o : wb32_master_out; +signal WB_master_i : wb32_master_in; + + +-- int eb if to cfg space +signal eb_2_CFG_slave : wb32_slave_in; +signal CFG_2_eb_slave : wb32_slave_out; + + +-- ext if to cfg space +signal EXT_2_CFG_slave : wb32_slave_in; +signal CFG_2_EXT_slave : wb32_slave_out; + +signal CFG_MY_MAC : std_logic_vector(6*8-1 downto 0); +signal CFG_MY_IP : std_logic_vector(4*8-1 downto 0); +signal CFG_MY_PORT : std_logic_vector(2*8-1 downto 0); + + +-- TX CTRL <-> EBCORE signals + +signal EB_2_TXCTRL_wb_slave : wb32_slave_in; +signal TXCTRL_2_EB_wb_slave : wb32_slave_out; + + + +signal EB_2_RXCTRL_wb_master : wb32_master_in; +signal RXCTRL_2_EB_wb_master : wb32_master_out; + +-- RX CTRL <-> TXCTRL signals +signal RXCTRL_2_TXCTRL_reply_MAC : std_logic_vector(47 downto 0); +signal RXCTRL_2_TXCTRL_reply_IP : std_logic_vector(31 downto 0); +signal RXCTRL_2_TXCTRL_reply_PORT : std_logic_vector(15 downto 0); +signal RXCTRL_2_TXCTRL_TOL : std_logic_vector(15 downto 0); +signal RXCTRL_2_CORE_LEN : std_logic_vector(15 downto 0); +signal RXCTRL_2_TXCTRL_valid : std_logic; + +--EB <-> TXCTRL +signal EB_2_TXCTRL_wb_master : wb32_master_out; +signal TXCTRL_2_EB_wb_master : wb32_master_in; + +--EB <-> RXCTRL +signal EB_2_RXCTRL_wb_slave : wb32_slave_out; +signal RXCTRL_2_EB_wb_slave : wb32_slave_in; + +signal EB_RX_i : wb16_slave_in; +signal EB_RX_o : wb16_slave_out; + +signal EB_TX_i : wb16_master_in; +signal EB_TX_o : wb16_master_out; + +component binary_sink is +generic(filename : string := "123.pcap"; wordsize : natural := 64; endian : natural := 0); +port( + clk_i : in std_logic; --clock + nRST_i : in std_logic; + + rdy_o : out std_logic; + + sample_i : in std_logic; + valid_i : in std_logic; + data_i : in std_logic_vector(wordsize-1 downto 0) +); +end component; + + + +component EB_TX_CTRL is +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + --Eth MAC WB Streaming signals + wb_slave_i : in wb32_slave_in; + wb_slave_o : out wb32_slave_out; + + TX_master_o : out wb16_master_out; --! Wishbone master output lines + TX_master_i : in wb16_master_in; --! + + + + reply_MAC_i : in std_logic_vector(47 downto 0); + reply_IP_i : in std_logic_vector(31 downto 0); + reply_PORT_i : in std_logic_vector(15 downto 0); + + TOL_i : in std_logic_vector(15 downto 0); + + valid_i : in std_logic + +); +end component; + +component EB_RX_CTRL is + port( + clk_i : in std_logic; + nRst_i : in std_logic; + + + RX_slave_o : out wb16_slave_out; --! Wishbone master output lines + RX_slave_i : in wb16_slave_in; --! + + --Eth MAC WB Streaming signals + wb_master_i : in wb32_master_in; + wb_master_o : out wb32_master_out; + + reply_MAC_o : out std_logic_vector(6*8-1 downto 0); + reply_IP_o : out std_logic_vector(4*8-1 downto 0); + reply_Port_o : out std_logic_vector(2*8-1 downto 0); + TOL_o : out std_logic_vector(2*8-1 downto 0); + payload_len_o : out std_logic_vector(2*8-1 downto 0); + + my_mac_i : in std_logic_vector(6*8-1 downto 0); + my_ip_i : in std_logic_vector(4*8-1 downto 0); + my_port_i : in std_logic_vector(2*8-1 downto 0); + + valid_o : out std_logic + + ); +end component; + +component eb_2_wb_converter is +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + --Eth MAC WB Streaming signals + EB_RX_i : in wb32_slave_in; + EB_RX_o : out wb32_slave_out; + + EB_TX_i : in wb32_master_in; + EB_TX_o : out wb32_master_out; + + byte_count_rx_i : in std_logic_vector(15 downto 0); + + --config signals + config_master_i : in wb32_master_in; --! WB V4 interface to WB interconnect/device(s) + config_master_o : out wb32_master_out; --! WB V4 interface to WB interconnect/device(s) + + + --WB IC signals + WB_master_i : in wb32_master_in; + WB_master_o : out wb32_master_out + +); +end component; + +component eb_config is + port( + clk_i : in std_logic; --clock + nRST_i : in std_logic; + status_i : in std_logic; + status_en : in std_logic; + status_clr : in std_logic; + + my_mac_o : out std_logic_vector(6*8-1 downto 0); + my_ip_o : out std_logic_vector(4*8-1 downto 0); + my_port_o : out std_logic_vector(2*8-1 downto 0); + + local_slave_o : out wb32_slave_out; + local_slave_i : in wb32_slave_in; --! local Wishbone master lines + + eb_slave_o : out wb32_slave_out; --! EB Wishbone slave lines + eb_slave_i : in wb32_slave_in + ); +end component; + + +component eb_mini_master is +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + --Eth MAC WB Streaming signals + EB_RX_i : in wb32_slave_in; + EB_RX_o : out wb32_slave_out; + + EB_TX_i : in wb32_master_in; + EB_TX_o : out wb32_master_out; + + byte_count_rx_i : in std_logic_vector(15 downto 0); + + dst_MAC_o : out std_logic_vector(47 downto 0); + dst_IP_o : out std_logic_vector(31 downto 0); + dst_PORT_o : out std_logic_vector(15 downto 0); + + TOL_o : out std_logic_vector(15 downto 0); + hex_switch_i : in std_logic_vector(3 downto 0); + + valid_o : out std_logic + +); +end component; + + + begin + + debug_TX_TOL_o <= RXCTRL_2_TXCTRL_TOL; + + + + DEBUG_sink1_valid <= (RXCTRL_2_EB_wb_master.STB AND NOT EB_2_RXCTRL_wb_slave.STALL); + DEBUG_sink23_valid <= (DEBUG_WB_master_o.STB AND NOT WB_master_i.STALL); + + + + + + -- EB type conversions for WB daisychain +EB_2_TXCTRL_wb_slave <= wb32_slave_in(EB_2_TXCTRL_wb_master); +TXCTRL_2_EB_wb_master <= wb32_master_in(TXCTRL_2_EB_wb_slave); + +EB_2_RXCTRL_wb_master <= wb32_master_in(EB_2_RXCTRL_wb_slave); +RXCTRL_2_EB_wb_slave <= wb32_slave_in(RXCTRL_2_EB_wb_master); + +-- assign records to individual bus signals. +-- slave RX +EB_RX_i.CYC <= snk_CYC_i; +EB_RX_i.STB <= snk_STB_i; +EB_RX_i.DAT <= snk_DAT_i; +EB_RX_i.WE <= snk_WE_i; +snk_STALL_o <= EB_RX_o.STALL; +snk_ERR_o <= EB_RX_o.ERR; +snk_ACK_o <= EB_RX_o.ACK; + +-- master TX +src_CYC_o <= EB_TX_o.CYC; +src_STB_o <= EB_TX_o.STB; +src_DAT_o <= EB_TX_o.DAT; +src_WE_o <= EB_TX_o.WE; +EB_TX_i.STALL <= src_STALL_i; +EB_TX_i.ERR <= src_ERR_i; +EB_TX_i.ACK <= src_ACK_i; + +master_cyc_o <= DEBUG_WB_master_o.CYC; +master_we_o <= DEBUG_WB_master_o.WE; +master_stb_o <= DEBUG_WB_master_o.STB; +master_sel_o <= DEBUG_WB_master_o.SEL; +master_adr_o <= DEBUG_WB_master_o.ADR; +master_dat_o <= DEBUG_WB_master_o.DAT; +WB_master_i.DAT <= master_dat_i; +WB_master_i.STALL <= master_stall_i; +WB_master_i.ACK <= master_ack_i; + + + +-- ext interface to cfg space +EXT_2_CFG_slave.CYC <= cfg_slave_cyc_i; +EXT_2_CFG_slave.STB <= cfg_slave_stb_i; +EXT_2_CFG_slave.WE <= cfg_slave_we_i; +EXT_2_CFG_slave.SEL <= cfg_slave_sel_i; +EXT_2_CFG_slave.ADR <= cfg_slave_adr_i; +EXT_2_CFG_slave.DAT <= cfg_slave_dat_i; + +cfg_slave_ack_o <= CFG_2_EXT_slave.ACK; +cfg_slave_stall_o <= CFG_2_EXT_slave.STALL; +cfg_slave_err_o <= CFG_2_EXT_slave.ERR; +cfg_slave_dat_o <= CFG_2_EXT_slave.DAT; + + + + +src_adr_o <= (others => '0'); +src_sel_o <= (others => '1'); + +master : if(g_master_slave = "MASTER") generate + + minimaster : eb_mini_master + port map( + --general + clk_i => clk_i, + nRst_i => nRst_i, + + --Eth MAC WB Streaming signals + EB_RX_i => RXCTRL_2_EB_wb_slave, + EB_RX_o => EB_2_RXCTRL_wb_slave, + + EB_TX_i => TXCTRL_2_EB_wb_master, + EB_TX_o => EB_2_TXCTRL_wb_master, + + byte_count_rx_i => RXCTRL_2_TXCTRL_TOL, + + dst_MAC_o => RXCTRL_2_TXCTRL_reply_MAC, + dst_IP_o => RXCTRL_2_TXCTRL_reply_IP, + dst_PORT_o => RXCTRL_2_TXCTRL_reply_PORT, + TOL_o => RXCTRL_2_TXCTRL_TOL, + hex_switch_i => hex_switch_i, + valid_o => RXCTRL_2_TXCTRL_valid + ); + + TXCTRL : EB_TX_CTRL + port map + ( + clk_i => clk_i, + nRST_i => nRst_i, + + --Eth MAC WB Streaming signals + wb_slave_i => EB_2_TXCTRL_wb_slave, + wb_slave_o => TXCTRL_2_EB_wb_slave, + + TX_master_o => EB_TX_o, + TX_master_i => EB_TX_i, --! + + reply_MAC_i => RXCTRL_2_TXCTRL_reply_MAC, + reply_IP_i => RXCTRL_2_TXCTRL_reply_IP, + reply_PORT_i => RXCTRL_2_TXCTRL_reply_PORT, + + TOL_i => RXCTRL_2_TXCTRL_TOL, + + valid_i => RXCTRL_2_TXCTRL_valid + + ); + + + RXCTRL: EB_RX_CTRL + port map ( clk_i => clk_i, + nRst_i => nRst_i, + wb_master_i => EB_2_RXCTRL_wb_master, + wb_master_o => RXCTRL_2_EB_wb_master, + + RX_slave_o => EB_RX_o, + RX_slave_i => EB_RX_i, + + reply_MAC_o => RXCTRL_2_TXCTRL_reply_MAC, + reply_IP_o => RXCTRL_2_TXCTRL_reply_IP, + reply_PORT_o => RXCTRL_2_TXCTRL_reply_PORT, + TOL_o => RXCTRL_2_TXCTRL_TOL, + my_mac_i => CFG_MY_MAC, + my_ip_i => CFG_MY_IP, + my_port_i => CFG_MY_PORT, + valid_o => RXCTRL_2_TXCTRL_valid); + + + +end generate; + +slave : if(g_master_slave = "SLAVE") generate + + TXCTRL : EB_TX_CTRL + port map + ( + clk_i => clk_i, + nRST_i => nRst_i, + + --Eth MAC WB Streaming signals + wb_slave_i => EB_2_TXCTRL_wb_slave, + wb_slave_o => TXCTRL_2_EB_wb_slave, + + TX_master_o => EB_TX_o, + TX_master_i => EB_TX_i, --! + + reply_MAC_i => RXCTRL_2_TXCTRL_reply_MAC, + reply_IP_i => RXCTRL_2_TXCTRL_reply_IP, + reply_PORT_i => RXCTRL_2_TXCTRL_reply_PORT, + + TOL_i => RXCTRL_2_TXCTRL_TOL, + + valid_i => RXCTRL_2_TXCTRL_valid + + ); + + + RXCTRL: EB_RX_CTRL + port map ( clk_i => clk_i, + nRst_i => nRst_i, + wb_master_i => EB_2_RXCTRL_wb_master, + wb_master_o => RXCTRL_2_EB_wb_master, + + RX_slave_o => EB_RX_o, + RX_slave_i => EB_RX_i, + + reply_MAC_o => RXCTRL_2_TXCTRL_reply_MAC, + reply_IP_o => RXCTRL_2_TXCTRL_reply_IP, + reply_PORT_o => RXCTRL_2_TXCTRL_reply_PORT, + TOL_o => RXCTRL_2_TXCTRL_TOL, + payload_len_o => RXCTRL_2_CORE_LEN, + my_mac_i => CFG_MY_MAC, + my_ip_i => CFG_MY_IP, + my_port_i => CFG_MY_PORT, + valid_o => RXCTRL_2_TXCTRL_valid); + + + + + EB : eb_2_wb_converter + port map( + --general + clk_i => clk_i, + nRst_i => nRst_i, + + --Eth MAC WB Streaming signals + EB_RX_i => RXCTRL_2_EB_wb_slave, + EB_RX_o => EB_2_RXCTRL_wb_slave, + + EB_TX_i => TXCTRL_2_EB_wb_master, + EB_TX_o => EB_2_TXCTRL_wb_master, + + byte_count_rx_i => RXCTRL_2_CORE_LEN, + + config_master_i => CFG_2_eb_slave, + config_master_o => eb_2_CFG_slave, + + --WB IC signals + WB_master_i => WB_master_i, + WB_master_o => DEBUG_WB_master_o + ); + + + s_status_en <= WB_master_i.ACK OR WB_master_i.ERR; + s_status_clr <= NOT DEBUG_WB_master_o.CYC; + + cfg_space : eb_config + port map( + --general + clk_i => clk_i, + nRst_i => nRst_i, + + status_i => WB_master_i.ERR, + status_en => s_status_en, + status_clr => s_status_clr, + + my_mac_o => CFG_MY_MAC, + my_ip_o => CFG_MY_IP, + my_port_o => CFG_MY_PORT, + + local_slave_o => CFG_2_EXT_slave, + local_slave_i => EXT_2_CFG_slave, + + eb_slave_o => CFG_2_eb_slave, + eb_slave_i => eb_2_CFG_slave + ); + + +end generate; + +end behavioral; diff --git a/hdl/EB_SPEC_Test/EB_HDR_pkg.vhd b/hdl/EB_SPEC_Test/EB_HDR_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6a3d0bddf3692100e14297321adf3a93a7a1d706 --- /dev/null +++ b/hdl/EB_SPEC_Test/EB_HDR_pkg.vhd @@ -0,0 +1,408 @@ +--! @file EB_HDR_pkg.vhd +--! @brief EtherBone Header definitions - Eth, IPV4, UDP, EB +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +--! Additional library +library work; +--! Additional packages +--use work.XXX.all; + + +package EB_HDR_PKG is + + +--Constants ------------------------ +constant c_MY_MAC : std_logic_vector(6*8-1 downto 0) := x"D15EA5EDBEEF"; +constant c_PREAMBLE : std_logic_vector(8*8-1 downto 0) := x"55555555555555D5"; + +constant c_MY_IP : std_logic_vector(4*8-1 downto 0) := x"C0A80164"; -- fixed address for now. 192.168.1.100 +constant c_BROADCAST_IP : std_logic_vector(4*8-1 downto 0) := x"FFFFFFFF"; +constant c_PRO_UDP : std_logic_vector(1*8-1 downto 0) := x"11"; + +constant c_EB_MAGIC_WORD : std_logic_vector(15 downto 0) := x"4E6F"; +constant c_EB_PORT : std_logic_vector(15 downto 0) := x"EBD0"; +constant c_EB_VER : std_logic_vector(3 downto 0) := x"1"; +constant c_MY_EB_PORT_SIZE : std_logic_vector(3 downto 0) := x"4"; +constant c_MY_EB_ADDR_SIZE : std_logic_vector(3 downto 0) := x"4"; + +constant c_EB_PORT_SIZE_n : natural := 32; +constant c_EB_ADDR_SIZE_n : natural := 32; + + +constant c_ETH_HLEN : natural := 14; +constant c_IPV4_HLEN : natural := 20; +constant c_UDP_HLEN : natural := 8; +constant c_HDR_LEN : natural := (c_ETH_HLEN + c_IPV4_HLEN + c_UDP_HLEN); +----------------------------------- + +type ETH_HDR is record + --PRE_SFD : std_logic_vector((8*8)-1 downto 0); + DST : std_logic_vector((6*8)-1 downto 0); + SRC : std_logic_vector((6*8)-1 downto 0); + TPID : std_logic_vector((2*8)-1 downto 0); + PCP : std_logic_vector(2 downto 0); + CFI : std_logic; + VID : std_logic_vector(11 downto 0); + TYP : std_logic_vector((2*8)-1 downto 0); + +end record; + +--define IPV4 header +type IPV4_HDR is record + + -- RX only, use constant fields for TX -------- + VER : std_logic_vector(3 downto 0); + IHL : std_logic_vector(3 downto 0); + TOS : std_logic_vector(7 downto 0); + TOL : std_logic_vector(15 downto 0); + ID : std_logic_vector(15 downto 0); + FLG : std_logic_vector(2 downto 0); + FRO : std_logic_vector(12 downto 0); + TTL : std_logic_vector(7 downto 0); + PRO : std_logic_vector(7 downto 0); + SUM : std_logic_vector(15 downto 0); + SRC : std_logic_vector(31 downto 0); + DST : std_logic_vector(31 downto 0); + --- options (optional) here +end record; + + + +--define UDP header +type UDP_HDR is record + SRC_PORT : std_logic_vector(15 downto 0); + DST_PORT : std_logic_vector(15 downto 0); + MLEN : std_logic_vector(15 downto 0); + SUM : std_logic_vector(15 downto 0); +end record; + +--define Etherbone header +type EB_HDR is record + EB_MAGIC : std_logic_vector(15 downto 0); + VER : std_logic_vector(3 downto 0); + RESERVED1 : std_logic_vector(1 downto 0); + PROBE_RES : std_logic; + PROBE : std_logic; + ADDR_SIZE : std_logic_vector(3 downto 0); + PORT_SIZE : std_logic_vector(3 downto 0); +end record; + +type EB_CYC is record + + BCA_CFG : std_logic; + RCA_CFG : std_logic; + RD_FIFO : std_logic; + RESERVED1 : std_logic; + + DROP_CYC : std_logic; + WCA_CFG : std_logic; + WR_FIFO : std_logic; + RESERVED2 : std_logic; + + RESERVED3 : std_logic_vector(7 downto 0); + WR_CNT : unsigned(7 downto 0); + RD_CNT : unsigned(7 downto 0); +end record; + + + + +--conversion function prototyes + +-- Eth +function TO_ETH_HDR(X : std_logic_vector) +return ETH_HDR; + +function TO_STD_LOGIC_VECTOR(X : ETH_HDR) +return std_logic_vector; + +function INIT_ETH_HDR(SRC_MAC : std_logic_vector) +return ETH_HDR; + + +-- IPV4 +function TO_IPV4_HDR(X : std_logic_vector) +return IPV4_HDR; + +function TO_STD_LOGIC_VECTOR(X : IPV4_HDR) +return std_logic_vector; + +function INIT_IPV4_HDR(SRC_IP : std_logic_vector) +return IPV4_HDR; + +-- UDP +function TO_UDP_HDR(X : std_logic_vector) +return UDP_HDR; + +function TO_STD_LOGIC_VECTOR(X : UDP_HDR) +return std_logic_vector; + +function INIT_UDP_HDR(SRC_PORT : std_logic_vector) +return UDP_HDR; + +-- EB HDR +function TO_EB_HDR(X : std_logic_vector) +return EB_HDR; + +function TO_STD_LOGIC_VECTOR(X : EB_HDR) +return std_logic_vector; + +function INIT_EB_HDR +return EB_HDR; + +-- EB CYC +function TO_EB_CYC(X : std_logic_vector) +return EB_CYC; + +function TO_STD_LOGIC_VECTOR(X : EB_CYC) +return std_logic_vector; + +end EB_HDR_PKG; + +package body EB_HDR_PKG is + +--conversion functions + +-- ETH Functions +-- check for VLAN tag +function TO_ETH_HDR(X : std_logic_vector) +return ETH_HDR is + variable tmp : ETH_HDR; + begin + tmp.DST := X(X'LEFT downto X'LENGTH-(6*8)); + tmp.SRC := X(X'LEFT-(6*8) downto X'LENGTH-(12*8)); + +-- if(X(X'LEFT-(12*8) downto X'LENGTH-(14*8)) = x"8100") then --VLAN tag detected +-- tmp.TPID := X(X'LEFT-(12*8) downto X'LENGTH-(14*8)); +-- tmp.PCP := X(X'LEFT-(14*8) downto X'LENGTH-(14*8)-3); +-- tmp.CFI := X(X'LENGTH-(14*8)-4); +-- tmp.VID := X(X'LEFT-(14*8)-4 downto X'LENGTH-(16*8)); +-- tmp.TYP := X(X'LEFT-(16*8) downto X'LENGTH-(18*8)); +-- else + + tmp.TYP := X(X'LEFT-(12*8) downto X'LENGTH-(14*8)); + --end if; + + return tmp; +end function TO_ETH_HDR; + + + +function TO_STD_LOGIC_VECTOR(X : ETH_HDR) +return std_logic_vector is + variable tmp : std_logic_vector((6+6+2)*8-1 downto 0) := (others => '0'); + begin + + tmp := X.DST & X.SRC & X.TYP; + + return tmp; +end function TO_STD_LOGIC_VECTOR; + + +function INIT_ETH_HDR(SRC_MAC : std_logic_vector) +return ETH_HDR is +variable tmp : ETH_HDR; + begin + --tmp.PRE_SFD := c_PREAMBLE; -- 4 + tmp.DST := (others => '1'); -- 4 + tmp.SRC := SRC_MAC; -- 8 + --tmp.TPID := (others => '0'); + --tmp.PCP := (others => '0'); + --tmp.CFI := '0'; + --tmp.VID := (others => '0'); + tmp.TYP := x"0800"; --type ID + return tmp; +end function INIT_ETH_HDR; + +-- IPV4 functions + +function TO_STD_LOGIC_VECTOR(X : IPV4_HDR) +return std_logic_vector is + variable tmp : std_logic_vector(159 downto 0) := (others => '0'); + begin + tmp := X.VER & X.IHL & X.TOS & X.TOL & X.ID & X.FLG & X.FRO & X.TTL & X.PRO & X.SUM & X.SRC & X.DST ; + return tmp; +end function TO_STD_LOGIC_VECTOR; + +function INIT_IPV4_HDR(SRC_IP : std_logic_vector) --loads constants into a given IPV4_HDR record +return IPV4_HDR is +variable tmp : IPV4_HDR; + begin + tmp.VER := x"4"; -- 4b + tmp.IHL := x"5"; -- 4b + tmp.TOS := x"00"; -- 8b + tmp.TOL := (others => '0'); --16b + tmp.ID := (others => '0'); --16b + tmp.FLG := "010"; -- 3b + tmp.FRO := (others => '0'); -- 0b + tmp.TTL := x"40"; -- 8b --64 Hops + tmp.PRO := c_PRO_UDP; -- 8b --UDP + --tmp.PRO := x"88"; -- 8b --UDP Lite + tmp.SUM := (others => '0'); --16b + tmp.SRC := SRC_IP; --32b -- SRC is already known + tmp.DST := (others => '1'); --32b + + return tmp; +end function INIT_IPV4_HDR; + +function TO_IPV4_HDR(X : std_logic_vector) +return IPV4_HDR is + variable tmp : IPV4_HDR; + begin + tmp.VER := X(159 downto 156); + tmp.IHL := X(155 downto 152); + tmp.TOS := X(151 downto 144); + tmp.TOL := X(143 downto 128); + tmp.ID := X(127 downto 112); + tmp.FLG := X(111 downto 109); + tmp.FRO := X(108 downto 96); + tmp.TTL := X(95 downto 88); + tmp.PRO := X(87 downto 80); + tmp.SUM := X(79 downto 64); + tmp.SRC := X(63 downto 32); + tmp.DST := X(31 downto 0); + + return tmp; +end function TO_IPV4_HDR; + +-- END IPV4 -------------------------------------------------------------- + + +-- UDP functions +function TO_STD_LOGIC_VECTOR(X : UDP_HDR) +return std_logic_vector is + variable tmp : std_logic_vector(63 downto 0) := (others => '0'); + begin + tmp := X.SRC_PORT & X.DST_PORT & X.MLEN & X.SUM; + return tmp; +end function TO_STD_LOGIC_VECTOR; + +function TO_UDP_HDR(X : std_logic_vector) +return UDP_HDR is + variable tmp : UDP_HDR; + begin + tmp.SRC_PORT := X(63 downto 48); + tmp.DST_PORT := X(47 downto 32); + tmp.MLEN := X(31 downto 16); + tmp.SUM := X(15 downto 0); + return tmp; +end function TO_UDP_HDR; + +function INIT_UDP_HDR(SRC_PORT : std_logic_vector) +return UDP_HDR is + variable tmp : UDP_HDR; + begin + tmp.SRC_PORT := SRC_PORT; --16 --E ther B one D ata 0 bject + tmp.DST_PORT := c_EB_PORT; --16 --E ther B one D ata 0 bject + tmp.MLEN := (others => '0'); --16 + tmp.SUM := (others => '0'); --16 + return tmp; +end function INIT_UDP_HDR; + +-- END UDP -------------- END UDP ---------------------------------------- + +-- EB functions +function TO_EB_HDR(X : std_logic_vector) +return EB_HDR is + variable tmp : EB_HDR; + begin + + tmp.EB_MAGIC := X(31 downto 16); + tmp.VER := X(15 downto 12); + tmp.RESERVED1 := X(11 downto 10); + tmp.PROBE_RES := X(9); + tmp.PROBE := X(8); + tmp.ADDR_SIZE := X(7 downto 4); + tmp.PORT_SIZE := X(3 downto 0); + return tmp; +end function TO_EB_HDR; + +function TO_STD_LOGIC_VECTOR(X : EB_HDR) +return std_logic_vector is + variable tmp : std_logic_vector(31 downto 0) := (others => '0'); + begin + tmp := X.EB_MAGIC & X.VER & X.RESERVED1 & X.PROBE_RES & X.PROBE & X.ADDR_SIZE & X.PORT_SIZE; + return tmp; +end function TO_STD_LOGIC_VECTOR; + +function INIT_EB_HDR +return EB_HDR is + variable tmp : EB_HDR; + begin + tmp.EB_MAGIC := c_EB_MAGIC_WORD;--16 + tmp.VER := c_EB_VER; -- 4 + tmp.RESERVED1 := (others => '0'); -- reserved 3bit + tmp.PROBE_RES := '0'; + tmp.PROBE := '0'; + tmp.ADDR_SIZE := c_MY_EB_ADDR_SIZE; -- 4 -- 32 bit + tmp.PORT_SIZE := c_MY_EB_PORT_SIZE; -- 4 + return tmp; +end function INIT_EB_HDR; + +function TO_EB_CYC(X : std_logic_vector) +return EB_CYC is + variable tmp : EB_CYC; + begin + tmp.BCA_CFG := X(31); + tmp.RCA_CFG := X(30); + tmp.RD_FIFO := X(29); + tmp.RESERVED1 := X(28); + tmp.DROP_CYC := X(27); + tmp.WCA_CFG := X(26); + tmp.WR_FIFO := X(25); + tmp.RESERVED2 := X(24); + tmp.RESERVED3 := X(23 downto 16); + tmp.WR_CNT := unsigned(X(15 downto 8)); + tmp.RD_CNT := unsigned(X(7 downto 0)); + + return tmp; +end function TO_EB_CYC; + +function TO_STD_LOGIC_VECTOR(X : EB_CYC) +return std_logic_vector is + variable tmp : std_logic_vector(31 downto 0) := (others => '0'); + begin + tmp := X.BCA_CFG & X.RCA_CFG & X.RD_FIFO & X.RESERVED1 & X.DROP_CYC & X.WCA_CFG & X.WR_FIFO & X.RESERVED2 + & X.RESERVED3 & std_logic_vector(X.WR_CNT) & std_logic_vector(X.RD_CNT) ; + return tmp; +end function TO_STD_LOGIC_VECTOR; + + +-- END EB -------------- END EB ---------------------------------------- + +---------------------------------------------------------------------------------- + +end package body; + + + + diff --git a/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd b/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6fe41ff249d9f2106fb829b3afdc45641a32076f --- /dev/null +++ b/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd @@ -0,0 +1,392 @@ +--! @file EB_RX_CTRL.vhd +--! @brief EtherBone RX Packet/Frame parser +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +--! Additional library +library work; +--! Additional packages +use work.EB_HDR_PKG.all; +--use work.EB_components_pkg.all; +use work.wb32_package.all; +use work.wb16_package.all; + +entity EB_RX_CTRL is + port( + clk_i : in std_logic; + nRst_i : in std_logic; + + + RX_slave_o : out wb16_slave_out; --! Wishbone master output lines + RX_slave_i : in wb16_slave_in; --! + + --Eth MAC WB Streaming signals + wb_master_i : in wb32_master_in; + wb_master_o : out wb32_master_out; + + reply_MAC_o : out std_logic_vector(6*8-1 downto 0); + reply_IP_o : out std_logic_vector(4*8-1 downto 0); + reply_Port_o : out std_logic_vector(2*8-1 downto 0); + TOL_o : out std_logic_vector(2*8-1 downto 0); + payload_len_o : out std_logic_vector(2*8-1 downto 0); + + my_mac_i : in std_logic_vector(6*8-1 downto 0); + my_ip_i : in std_logic_vector(4*8-1 downto 0); + my_port_i : in std_logic_vector(2*8-1 downto 0); + + valid_o : out std_logic + + ); +end entity; + + +architecture behavioral of EB_RX_CTRL is + + component WB_bus_adapter_streaming_sg + generic(g_adr_width_A : natural := 32; g_adr_width_B : natural := 32; + g_dat_width_A : natural := 32; g_dat_width_B : natural := 16; + g_pipeline : natural + ); + port( + clk_i : in std_logic; + nRst_i : in std_logic; + A_CYC_i : in std_logic; + A_STB_i : in std_logic; + A_ADR_i : in std_logic_vector(g_adr_width_A-1 downto 0); + A_SEL_i : in std_logic_vector(g_dat_width_A/8-1 downto 0); + A_WE_i : in std_logic; + A_DAT_i : in std_logic_vector(g_dat_width_A-1 downto 0); + A_ACK_o : out std_logic; + A_ERR_o : out std_logic; + A_RTY_o : out std_logic; + A_STALL_o : out std_logic; + A_DAT_o : out std_logic_vector(g_dat_width_A-1 downto 0); + B_CYC_o : out std_logic; + B_STB_o : out std_logic; + B_ADR_o : out std_logic_vector(g_adr_width_B-1 downto 0); + B_SEL_o : out std_logic_vector(g_dat_width_B/8-1 downto 0); + B_WE_o : out std_logic; + B_DAT_o : out std_logic_vector(g_dat_width_B-1 downto 0); + B_ACK_i : in std_logic; + B_ERR_i : in std_logic; + B_RTY_i : in std_logic; + B_STALL_i : in std_logic; + B_DAT_i : in std_logic_vector(g_dat_width_B-1 downto 0) + ); + end component; + + component sipo_flag is + generic(g_width_IN : natural := 16; g_width_OUT : natural := 32); + port( + clk_i : in std_logic; + nRst_i : in std_logic; + + d_i : in std_logic_vector(g_width_IN-1 downto 0); + en_i : in std_logic; + clr_i : in std_logic; + + q_o : out std_logic_vector(g_width_OUT-1 downto 0); + full_o : out std_logic; + empty_o : out std_logic + ); + end component; + + signal conv_A : wb16_slave_out; --! Wishbone master output lines + signal conv_B : wb32_master_out; --! + + +-- main FSM + type st is (IDLE, HDR_RECEIVE, CALC_CHKSUM, WAIT_STATE, CHECK_HDR, PAYLOAD_RECEIVE, error); + signal state_RX : st := IDLE; + type st_hdr is (ETH, IPV4, UDP); + signal state_HDR : st_hdr := ETH; + +--split shift register output and convert to hdr records + signal ETH_RX : ETH_HDR; + signal IPV4_RX : IPV4_HDR; + signal UDP_RX : UDP_HDR; + signal payload_len : std_logic_vector(2*8-1 downto 0); + +signal RX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8-1 downto 0) ; + +--forking the bus + type stmux is (HEADER, PAYLOAD); + signal state_mux : stmux := HEADER; + signal RX_hdr_o : wb16_slave_out; --! Wishbone master output lines + signal wb_payload_stb_o : wb32_master_out; + +--shift register input and control signals + signal counter_input : natural; + signal counter_clr : std_logic; + signal hdr_done : std_logic; + + signal sipo_clr : std_logic; + signal sipo_full : std_logic; + signal sipo_empty : std_logic; + signal sipo_en : std_logic; + + + + signal PAYLOAD_STB_i : std_logic; + signal PAYLOAD_CYC_i : std_logic; + signal HDR_STALL : std_logic; + + + +begin + + + + Shift_in : sipo_flag generic map (16, c_IPV4_HLEN*8) --IP header is longest possibility + port map (d_i => RX_slave_i.DAT, + q_o => RX_HDR_slv, + clk_i => clk_i, + nRST_i => nRST_i, + en_i => sipo_en, + clr_i => sipo_clr, + full_o => sipo_full, + empty_o => sipo_empty); + + + + + + sh : sipo_en <= '1' when (RX_slave_i.CYC = '1' and RX_slave_i.STB = '1') + else '0'; + + +-- convert streaming input from 16 to 32 bit data width + uut : WB_bus_adapter_streaming_sg generic map (g_adr_width_A => 32, + g_adr_width_B => 32, + g_dat_width_A => 16, + g_dat_width_B => 32, + g_pipeline => 3) + port map (clk_i => clk_i, + nRst_i => nRst_i, + A_CYC_i => PAYLOAD_CYC_i, + A_STB_i => PAYLOAD_STB_i, + A_ADR_i => RX_slave_i.ADR, + A_SEL_i => RX_slave_i.SEL, + A_WE_i => RX_slave_i.WE, + A_DAT_i => RX_slave_i.DAT, + A_ACK_o => conv_A.ACK, + A_ERR_o => conv_A.ERR, + A_RTY_o => conv_A.RTY, + A_STALL_o => conv_A.STALL, + A_DAT_o => conv_A.DAT, + B_CYC_o => conv_B.CYC, + B_STB_o => conv_B.STB, + B_ADR_o => conv_B.ADR, + B_SEL_o => conv_B.SEL, + B_WE_o => conv_B.WE, + B_DAT_o => conv_B.DAT, + B_ACK_i => wb_master_i.ACK, + B_ERR_i => wb_master_i.ERR, + B_RTY_i => wb_master_i.RTY, + B_STALL_i => wb_master_i.STALL, + B_DAT_i => wb_master_i.DAT); + + + + RX_hdr_o.STALL <= HDR_STALL; + + MUX_RX : with state_mux select + RX_slave_o <= conv_A when PAYLOAD, + RX_hdr_o when others; + + MUX_PAYLOADSTB : with state_mux select + PAYLOAD_STB_i <= RX_slave_i.STB when PAYLOAD, + '0' when others; + + MUX_PAYLOADCYC : with state_mux select + PAYLOAD_CYC_i <= RX_slave_i.CYC when PAYLOAD, + '0' when others; + + + MUX_WB : with state_mux select + wb_master_o <= conv_B when PAYLOAD, + wb_payload_stb_o when others; + + + +--postpone VLAN support + reply_MAC_o <= ETH_RX.SRC; + reply_IP_o <= IPV4_RX.SRC; + reply_PORT_o <= UDP_RX.SRC_PORT; + payload_len_o <= payload_len; + TOL_o <= IPV4_RX.TOL; + + +count_bytes : process(clk_i) +begin + if rising_edge(clk_i) then + + --========================================================================== + -- SYNC RESET + --========================================================================== + if (nRST_i = '0') then + + state_HDR <= ETH; + counter_input <= 0; + hdr_done <= '0'; + state_mux <= HEADER; + HDR_STALL <= '0'; + else + + if(counter_clr = '1') then + state_HDR <= ETH; + counter_input <= 0; + hdr_done <= '0'; + state_mux <= HEADER; + + end if; + + + + if(state_RX = HDR_RECEIVE) then + if(RX_slave_i.CYC = '1' and RX_slave_i.STB = '1') then + counter_input <= counter_input +2; + + end if; + + case state_HDR is + when ETH => if(counter_input >= c_ETH_HLEN-2) then + counter_input <= 0; + ETH_RX <= TO_ETH_HDR(RX_HDR_slv(c_ETH_HLEN*8-1 downto 0)); + state_HDR <= IPV4; + end if; + when IPV4 => if(counter_input >= c_IPV4_HLEN-2) then + counter_input <= 0; + IPV4_RX <= TO_IPV4_HDR(RX_HDR_slv(c_IPV4_HLEN*8-1 downto 0)); + state_HDR <= UDP; + end if; + when UDP => + if((counter_input = c_UDP_HLEN-4) AND (RX_slave_i.CYC = '1' and RX_slave_i.STB = '1')) then + HDR_STALL <= '1'; + elsif(counter_input >= c_UDP_HLEN-2) then + counter_input <= 0; + UDP_RX <= TO_UDP_HDR(RX_HDR_slv(c_UDP_HLEN*8-1 downto 0)); + hdr_done <= '1'; + state_mux <= PAYLOAD; + HDR_STALL <= '0'; + + end if; + end case; + end if; + + end if; +end if; +end process; + + + + main_fsm : process(clk_i) + begin + if rising_edge(clk_i) then + + --========================================================================== + -- SYNC RESET + --========================================================================== + if (nRST_i = '0') then + + RX_hdr_o.ACK <= '0'; + + RX_hdr_o.ERR <= '0'; + RX_hdr_o.DAT <= (others => '0'); + RX_hdr_o.RTY <= '0'; + + wb_payload_stb_o.STB <= '0'; + wb_payload_stb_o.CYC <= '1'; + wb_payload_stb_o.WE <= '1'; + wb_payload_stb_o.SEL <= (others => '1'); + wb_payload_stb_o.ADR <= (others => '0'); + wb_payload_stb_o.DAT <= (others => '0'); + + + + payload_len <= (others => '0'); + + + else + counter_clr <= '0'; + sipo_clr <= '0'; + RX_hdr_o.ACK <= '0'; + if(RX_slave_i.CYC = '1' and RX_slave_i.STB = '1') then + RX_hdr_o.ACK <= '1'; + end if; + + + if((RX_slave_i.CYC = '0') and not ((state_RX = PAYLOAD_RECEIVE) or (state_RX = IDLE))) then --packet aborted before completion + state_RX <= error; + else + + case state_RX is + when IDLE => counter_clr <= '1'; + if(RX_slave_i.CYC = '1' and RX_slave_i.STB = '1') then + state_RX <= HDR_RECEIVE; + end if; + + when HDR_RECEIVE => if(hdr_done = '1') then + state_RX <= PAYLOAD_RECEIVE; + payload_len <= std_logic_vector(unsigned(UDP_RX .MLEN)-8); + valid_o <= '1'; + end if; + + + + when PAYLOAD_RECEIVE => if(RX_slave_i.CYC = '0') then + state_RX <= IDLE; + sipo_clr <= '1'; + + end if; + + when error => sipo_clr <= '1'; + + state_rx <= IDLE; + + when others => state_RX <= IDLE; + + + + end case; + + end if; + + + + end if; + end if; + + end process; + + + +end behavioral; diff --git a/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd b/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8860c6dc45f12d86b87ebf2ce88e59fe1cc8a97e --- /dev/null +++ b/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd @@ -0,0 +1,440 @@ +--! @file EB_TX_CTRL.vhd +--! @brief EtherBone TX Packet/Frame Builder +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +--! Additional library +library work; +--! Additional packages +use work.EB_HDR_PKG.all; +use work.wb32_package.all; +use work.wb16_package.all; + +entity EB_TX_CTRL is +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + --Eth MAC WB Streaming signals + wb_slave_i : in wb32_slave_in; + wb_slave_o : out wb32_slave_out; + + TX_master_o : out wb16_master_out; --! Wishbone master output lines + TX_master_i : in wb16_master_in; --! + + + + reply_MAC_i : in std_logic_vector(47 downto 0); + reply_IP_i : in std_logic_vector(31 downto 0); + reply_PORT_i : in std_logic_vector(15 downto 0); + + TOL_i : in std_logic_vector(15 downto 0); + + valid_i : in std_logic + +); +end entity; + + +architecture behavioral of EB_TX_CTRL is + +component EB_checksum is +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + en_i : in std_logic; + data_i : in std_logic_vector(15 downto 0); + + done_o : out std_logic; + sum_o : out std_logic_vector(15 downto 0) +); +end component; + +component WB_bus_adapter_streaming_sg + generic(g_adr_width_A : natural := 32; g_adr_width_B : natural := 32; + g_dat_width_A : natural := 32; g_dat_width_B : natural := 16; + g_pipeline : natural + ); + port( + clk_i : in std_logic; + nRst_i : in std_logic; + A_CYC_i : in std_logic; + A_STB_i : in std_logic; + A_ADR_i : in std_logic_vector(g_adr_width_A-1 downto 0); + A_SEL_i : in std_logic_vector(g_dat_width_A/8-1 downto 0); + A_WE_i : in std_logic; + A_DAT_i : in std_logic_vector(g_dat_width_A-1 downto 0); + A_ACK_o : out std_logic; + A_ERR_o : out std_logic; + A_RTY_o : out std_logic; + A_STALL_o : out std_logic; + A_DAT_o : out std_logic_vector(g_dat_width_A-1 downto 0); + B_CYC_o : out std_logic; + B_STB_o : out std_logic; + B_ADR_o : out std_logic_vector(g_adr_width_B-1 downto 0); + B_SEL_o : out std_logic_vector(g_dat_width_B/8-1 downto 0); + B_WE_o : out std_logic; + B_DAT_o : out std_logic_vector(g_dat_width_B-1 downto 0); + B_ACK_i : in std_logic; + B_ERR_i : in std_logic; + B_RTY_i : in std_logic; + B_STALL_i : in std_logic; + B_DAT_i : in std_logic_vector(g_dat_width_B-1 downto 0) + ); + end component; + +component piso_flag is +generic(g_width_IN : natural := 16; g_width_OUT : natural := 32); +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + d_i : in std_logic_vector(g_width_IN-1 downto 0); + en_i : in std_logic; + ld_i : in std_logic; + + q_o : out std_logic_vector(g_width_OUT-1 downto 0); + full_o : out std_logic; + empty_o : out std_logic +); + end component; + +signal conv_B : wb16_master_out; --! Wishbone master output lines +signal conv_A : wb32_slave_out; --! + +-- main FSM +type st is (IDLE, CALC_CHKSUM, WAIT_SEND_REQ, HDR_SEND, PAYLOAD_SEND, WAIT_IFGAP); +signal state_tx : st := IDLE; + +-- convert shift register input from hdr records to standard logic vectors and join them +signal ETH_TX : ETH_HDR; +signal IPV4_TX : IPV4_HDR; +signal UDP_TX : UDP_HDR; +signal TX_HDR_slv : std_logic_vector((c_ETH_HLEN + c_IPV4_HLEN + c_UDP_HLEN) * 8-1 downto 0); +alias ETH_TX_slv : std_logic_vector(c_ETH_HLEN*8-1 downto 0) is TX_HDR_slv((c_ETH_HLEN + c_IPV4_HLEN + c_UDP_HLEN)*8-1 downto (c_IPV4_HLEN + c_UDP_HLEN)*8); +alias IPV4_TX_slv : std_logic_vector(c_IPV4_HLEN*8-1 downto 0) is TX_HDR_slv((c_IPV4_HLEN + c_UDP_HLEN)*8-1 downto c_UDP_HLEN*8); +alias UDP_TX_slv : std_logic_vector(c_UDP_HLEN*8-1 downto 0) is TX_HDR_slv(c_UDP_HLEN*8-1 downto 0); + +--shift register output and control signals +signal s_out : std_logic_vector(31 downto 0); +signal sh_hdr_en : std_logic; +signal ld_hdr : std_logic; +signal counter_ouput : unsigned(7 downto 0); + +signal chksum_empty : std_logic; +signal hdr_empty : std_logic; +signal chksum_full : std_logic; +signal hdr_full : std_logic; + + +-- forking the bus +type stmux is (HEADER, PAYLOAD); +signal state_mux : stmux := HEADER; +signal TX_hdr_o : wb16_master_out; --! Wishbone master output lines +signal wb_payload_stall_o : wb32_slave_out; +signal stalled : std_logic; + +-- IP checksum generator +signal counter_chksum : unsigned(7 downto 0); +signal p_chk_vals : std_logic_vector(95 downto 0); +signal s_chk_vals : std_logic_vector(15 downto 0); +signal IP_chk_sum : std_logic_vector(15 downto 0); +signal sh_chk_en : std_logic; +signal calc_chk_en : std_logic; +signal ld_p_chk_vals : std_logic; --parallel load +signal chksum_done : std_logic; + +signal DEBUG_cmp_chksum : IPV4_HDR; + +signal PISO_STALL : std_logic; + +function calc_ip_chksum(input : IPV4_HDR) +return IPV4_HDR is + variable tmp : unsigned(c_IPV4_HLEN*8-1 downto 0); + variable output : IPV4_HDR; + variable tmp_sum : unsigned(31 downto 0) := (others => '0'); + variable tmp_slice : unsigned(15 downto 0); + begin + tmp := unsigned(to_std_logic_vector(input)); + for i in c_IPV4_HLEN*8/16-1 downto 0 loop + tmp_slice := tmp((i+1)*16-1 downto i*16); + tmp_sum := tmp_sum + (x"0000" & tmp_slice); + end loop; + tmp_sum := (x"0000" & tmp_sum(15 downto 0)) + (x"0000" + tmp_sum(31 downto 16)); + output.SUM := std_logic_vector(NOT(tmp_sum(15 downto 0) + tmp_sum(31 downto 16))); + return output; +end function calc_ip_chksum; + +begin + +ETH_TX_slv <= TO_STD_LOGIC_VECTOR(ETH_TX); +IPV4_TX_slv <= TO_STD_LOGIC_VECTOR(IPV4_TX); +UDP_TX_slv <= TO_STD_LOGIC_VECTOR(UDP_TX); + + +MUX_TX : with state_mux select +TX_master_o <= conv_B when PAYLOAD, + TX_hdr_o when others; + +MUX_WB : with state_mux select +wb_slave_o <= conv_A when others; --wb_payload_stall_o when HEADER, + + + +MUX_PISO : with state_mux select +PISO_STALL <= '1' when HEADER, + TX_master_i.STALL when others; + + +shift_hdr_chk_sum : piso_flag generic map( 96, 16) +port map ( d_i => p_chk_vals, + q_o => s_chk_vals, + clk_i => clk_i, + nRST_i => nRST_i, + en_i => sh_chk_en, + ld_i => ld_p_chk_vals, + full_o => chksum_full, + empty_o => chksum_empty +); + +p_chk_vals <= x"C511" & IPV4_TX.SRC & IPV4_TX.DST & IPV4_TX.TOL; + +chksum_generator: EB_checksum port map ( clk_i => clk_i, + nRst_i => nRst_i, + en_i => calc_chk_en, + data_i => s_chk_vals, + done_o => chksum_done, + sum_o => IP_chk_sum ); + + + + + + +Shift_out: piso_flag generic map ((c_ETH_HLEN + c_IPV4_HLEN + c_UDP_HLEN)*8, 16) + port map ( d_i => TX_HDR_slv , + q_o => TX_hdr_o.DAT, + clk_i => clk_i, + nRST_i => nRST_i, + en_i => sh_hdr_en , + ld_i => ld_hdr, + full_o => hdr_full, + empty_o => hdr_empty + ); + + + + + + +-- convert streaming input from 16 to 32 bit data width +uut: WB_bus_adapter_streaming_sg generic map ( g_adr_width_A => 32, + g_adr_width_B => 32, + g_dat_width_A => 32, + g_dat_width_B => 16, + g_pipeline => 3) + port map ( clk_i => clk_i, + nRst_i => nRst_i, + A_CYC_i => wb_slave_i.CYC, + A_STB_i => wb_slave_i.STB, + A_ADR_i => wb_slave_i.ADR, + A_SEL_i => wb_slave_i.SEL, + A_WE_i => wb_slave_i.WE, + A_DAT_i => wb_slave_i.DAT, + A_ACK_o => conv_A.ACK, + A_ERR_o => conv_A.ERR, + A_RTY_o => conv_A.RTY, + A_STALL_o => conv_A.STALL, + A_DAT_o => conv_A.DAT, + B_CYC_o => conv_B.CYC, + B_STB_o => conv_B.STB, + B_ADR_o => conv_B.ADR, + B_SEL_o => conv_B.SEL, + B_WE_o => conv_B.WE, + B_DAT_o => conv_B.DAT, + B_ACK_i => TX_master_i.ACK, + B_ERR_i => TX_master_i.ERR, + B_RTY_i => TX_master_i.RTY, + B_STALL_i => PISO_STALL, + B_DAT_i => TX_master_i.DAT); + + + + + +TX_hdr_o.STB <= '1' when state_tx = HDR_SEND AND hdr_empty = '0' +else '0'; + + +main_fsm : process(clk_i) +begin + if rising_edge(clk_i) then + + --========================================================================== + -- SYNC RESET + --========================================================================== + if (nRST_i = '0') then + ETH_TX <= INIT_ETH_HDR(c_MY_MAC); + IPV4_TX <= INIT_IPV4_HDR(c_MY_IP); + UDP_TX <= INIT_UDP_HDR(c_EB_PORT); + + IPV4_TX.TOL <= std_logic_vector(to_unsigned(112, 16)); + + TX_hdr_o.CYC <= '0'; + --TX_hdr_o.STB <= '0'; + TX_hdr_o.WE <= '1'; + TX_hdr_o.ADR <= (others => '0'); + TX_hdr_o.SEL <= (others => '1'); + + wb_payload_stall_o.STALL <= '1'; + wb_payload_stall_o.ACK <= '0'; + wb_payload_stall_o.DAT <= (others => '0'); + wb_payload_stall_o.ERR <= '0'; + wb_payload_stall_o.RTY <= '0'; + + state_mux <= HEADER; + + sh_hdr_en <= '0'; + ld_hdr <= '0'; + stalled <= '0'; + counter_ouput <= (others => '0'); + counter_chksum <= (others => '0'); + -- prepare chk sum field_tx_hdr, fill in reply IP and TOL field_tx_hdr when available + ld_p_chk_vals <= '0'; + sh_chk_en <= '0'; + calc_chk_en <= '0'; + else + + --TX_hdr_o.STB <= '0'; + + ld_hdr <= '0'; + sh_hdr_en <= '0'; + + ld_p_chk_vals <= '0'; + sh_chk_en <= '0'; + calc_chk_en <= '0'; + + case state_tx is + when IDLE => ETH_TX <= INIT_ETH_HDR (c_MY_MAC); + IPV4_TX <= INIT_IPV4_HDR(c_MY_IP); + UDP_TX <= INIT_UDP_HDR (c_EB_PORT); + state_mux <= HEADER; + counter_chksum <= (others => '0'); + counter_ouput <= (others => '0'); + + if(valid_i = '1') then + ETH_TX.DST <= reply_MAC_i; + IPV4_TX.DST <= reply_IP_i; + IPV4_TX.TOL <= TOL_i; + UDP_TX.MLEN <= std_logic_vector(unsigned(TOL_i)-((c_ETH_HLEN + c_IPV4_HLEN)/8)); + UDP_TX.DST_PORT <= reply_PORT_i; + ld_p_chk_vals <= '1'; + state_tx <= CALC_CHKSUM; + end if; + + when CALC_CHKSUM => if(chksum_empty = '0') then + sh_chk_en <= '1'; + calc_chk_en <= '1'; + counter_chksum <= counter_chksum +1; + else + if(chksum_done = '1') then + DEBUG_cmp_chksum <= calc_ip_chksum(IPV4_TX); + IPV4_TX.SUM <= IP_chk_sum; + ld_hdr <= '1'; + state_tx <= WAIT_SEND_REQ; + end if; + end if; + + when WAIT_SEND_REQ => state_mux <= HEADER; + if(wb_slave_i.CYC = '1') then + TX_hdr_o.CYC <= '1'; + --TX_hdr_o.STB <= '1'; + sh_hdr_en <= '1'; + state_tx <= HDR_SEND; + end if; + + + when HDR_SEND => if(hdr_empty = '0') then + --TX_hdr_o.STB <= '1'; + if(TX_master_i.STALL = '0') then + + sh_hdr_en <= '1'; + counter_ouput <= counter_ouput +1; + end if; + + -- if(TX_master_i.STALL = '1') then + -- stalled <= '1'; + + -- else + -- --TX_hdr_o.STB <= '1'; + -- if(stalled = '1') then + -- stalled <= '0'; + -- else + -- sh_TX_en <= '1'; + -- counter_ouput <= counter_ouput +1; + -- end if; + -- end if; + else + --TX_hdr_o.STB <= '0'; + state_mux <= PAYLOAD; + state_tx <= PAYLOAD_SEND; + end if; + + when PAYLOAD_SEND => if(wb_slave_i.CYC = '0' AND conv_B.STB = '0' AND TX_master_i.STALL = '0') then + state_tx <= WAIT_IFGAP; + state_mux <= HEADER; + TX_hdr_o.CYC <= '0'; + end if; + + when WAIT_IFGAP => --ensure interframe gap + if(counter_ouput < 10) then + counter_ouput <= counter_ouput +1; + else + state_tx <= IDLE; + end if; + + when others => state_tx <= IDLE; + + + end case; + + + + + end if; + end if; + +end process; + + + +end behavioral; diff --git a/hdl/EB_SPEC_Test/EB_checksum.vhd b/hdl/EB_SPEC_Test/EB_checksum.vhd new file mode 100644 index 0000000000000000000000000000000000000000..08e8ae7bc6484ca8a593164d29ad2804e2d6686b --- /dev/null +++ b/hdl/EB_SPEC_Test/EB_checksum.vhd @@ -0,0 +1,116 @@ +--! @file EB_checksum.vhd +--! @brief IP checksum generator for EtherBone +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +--! Additional library +library work; +--! Additional packages +use work.EB_HDR_PKG.all; + +entity EB_checksum is +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + en_i : in std_logic; + data_i : in std_logic_vector(15 downto 0); + + done_o : out std_logic; + sum_o : out std_logic_vector(15 downto 0) +); +end EB_checksum; + +architecture behavioral of EB_checksum is + +constant c_width_int : integer := 28; + +type st is (IDLE, ADDUP, CARRIES, FINALISE, OUTPUT); + +signal state : st := IDLE; +signal sum : unsigned(c_width_int-1 downto 0); +signal data : std_logic_vector(15 downto 0); + +begin + +adder: process(clk_i) +begin + if rising_edge(clk_i) then + --========================================================================== + -- SYNC RESET + --========================================================================== + if (nRST_i = '0') then + done_o <= '0'; + sum <= (others => '0'); + state <= IDLE; + + else + --register input data + data <= data_i; + sum_o <= NOT(std_logic_vector(sum(15 downto 0))); + + case state is + when IDLE => --clear internal states and output + done_o <= '0'; + sum <= (others => '0'); + + -- if enable flag is set, start checksum generation + if(en_i = '1') then + state <= ADDUP; + end if; + + when ADDUP => -- add up all incoming 16 bit words + sum <= sum + resize(unsigned(data), c_width_int); + + -- end of data block. add carry bits from hi word to low word + if(en_i = '0') then + state <= CARRIES; + end if; + + when CARRIES => sum <= resize(sum(15 downto 0), c_width_int) + resize(sum(c_width_int-1 downto 16), c_width_int); + state <= FINALISE; + + when FINALISE => -- add carry bits from hi word to low word again, in case last sum produced overflow + sum <= resize(sum(15 downto 0), c_width_int) + resize(sum(c_width_int-1 downto 16), c_width_int); + state <= OUTPUT; + + when OUTPUT => -- invert sum lo word, write to output. assert done flag + done_o <= '1'; + state <= IDLE; + + when others => state <= IDLE; + end case; + end if; + end if; + +end process; + +end behavioral; diff --git a/hdl/EB_SPEC_Test/Etherbone.sta.summary b/hdl/EB_SPEC_Test/Etherbone.sta.summary new file mode 100644 index 0000000000000000000000000000000000000000..130fd3335899408672f3f6c744922c7ab7b3c848 --- /dev/null +++ b/hdl/EB_SPEC_Test/Etherbone.sta.summary @@ -0,0 +1,41 @@ +------------------------------------------------------------ +TimeQuest Timing Analyzer Summary +------------------------------------------------------------ + +Type : Slow 900mV 85C Model Setup 'clk_i' +Slack : -3.902 +TNS : -3798.964 + +Type : Slow 900mV 85C Model Hold 'clk_i' +Slack : 0.315 +TNS : 0.000 + +Type : Slow 900mV 85C Model Minimum Pulse Width 'clk_i' +Slack : -2.846 +TNS : -2802.528 + +Type : Slow 900mV 0C Model Setup 'clk_i' +Slack : -3.821 +TNS : -3679.196 + +Type : Slow 900mV 0C Model Hold 'clk_i' +Slack : 0.315 +TNS : 0.000 + +Type : Slow 900mV 0C Model Minimum Pulse Width 'clk_i' +Slack : -2.846 +TNS : -2800.185 + +Type : Fast 900mV 0C Model Setup 'clk_i' +Slack : -1.220 +TNS : -951.719 + +Type : Fast 900mV 0C Model Hold 'clk_i' +Slack : 0.137 +TNS : 0.000 + +Type : Fast 900mV 0C Model Minimum Pulse Width 'clk_i' +Slack : -2.846 +TNS : -1170.141 + +------------------------------------------------------------ diff --git a/hdl/EB_SPEC_Test/WB_bus_adapter_streaming_sg.vhd b/hdl/EB_SPEC_Test/WB_bus_adapter_streaming_sg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..eec446f07a30401594613e66509c682891cfa08a --- /dev/null +++ b/hdl/EB_SPEC_Test/WB_bus_adapter_streaming_sg.vhd @@ -0,0 +1,295 @@ +--! @file WB_bus_adapter_streaming_sg.vhd +--! @brief WB adapters +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +-------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.vhdl_2008_workaround_pkg.all; + +entity WB_bus_adapter_streaming_sg is +generic(g_adr_width_A : natural := 16; g_adr_width_B : natural := 32; + g_dat_width_A : natural := 16; g_dat_width_B : natural := 32; + g_pipeline : natural := 2 + ); + -- pipeline: 0 => A-x, 1 x-B, 2 A-B +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + A_CYC_i : in std_logic; + A_STB_i : in std_logic; + A_ADR_i : in std_logic_vector(g_adr_width_A-1 downto 0); + A_SEL_i : in std_logic_vector(g_dat_width_A/8-1 downto 0); + A_WE_i : in std_logic; + A_DAT_i : in std_logic_vector(g_dat_width_A-1 downto 0); + A_ACK_o : out std_logic; + A_ERR_o : out std_logic; + A_RTY_o : out std_logic; + A_STALL_o : out std_logic; + A_DAT_o : out std_logic_vector(g_dat_width_A-1 downto 0); + + + B_CYC_o : out std_logic; + B_STB_o : out std_logic; + B_ADR_o : out std_logic_vector(g_adr_width_B-1 downto 0); + B_SEL_o : out std_logic_vector(g_dat_width_B/8-1 downto 0); + B_WE_o : out std_logic; + B_DAT_o : out std_logic_vector(g_dat_width_B-1 downto 0); + B_ACK_i : in std_logic; + B_ERR_i : in std_logic; + B_RTY_i : in std_logic; + B_STALL_i : in std_logic; + B_DAT_i : in std_logic_vector(g_dat_width_B-1 downto 0) + +); +end WB_bus_adapter_streaming_sg; + + + + +architecture behavioral of WB_bus_adapter_streaming_sg is + + constant c_adr_w_max : natural := maximum(g_adr_width_A, g_adr_width_B); + constant c_dat_w_max : natural := maximum(g_dat_width_A, g_dat_width_B); + constant c_sel_w_max : natural := maximum(g_dat_width_A, g_dat_width_B)/8; + constant c_adr_w_min : natural := minimum(g_adr_width_A, g_adr_width_B); + constant c_dat_w_min : natural := minimum(g_dat_width_A, g_dat_width_B); + constant c_sel_w_min : natural := minimum(g_dat_width_A, g_dat_width_B)/8; + + signal sipo_d : std_logic_vector(c_dat_w_min-1 downto 0); + signal sipo_q : std_logic_vector(c_dat_w_max-1 downto 0); + signal piso_d : std_logic_vector(c_dat_w_max-1 downto 0); + signal piso_q : std_logic_vector(c_dat_w_min-1 downto 0); + + -- direct adapter signals + constant c_adr_pad : std_logic_vector(c_adr_w_max-1 downto 0) := (others => '0'); + constant c_sel_pad : std_logic_vector(c_sel_w_max-1 downto 0) := (others => '0'); + constant c_dat_pad : std_logic_vector(c_dat_w_max-1 downto 0) := (others => '0'); + + signal adr : std_logic_vector(c_adr_w_max-1 downto 0); + signal slave_dat : std_logic_vector(c_dat_w_max-1 downto 0); + signal master_dat : std_logic_vector(c_dat_w_max-1 downto 0); + signal sel : std_logic_vector(c_sel_w_max-1 downto 0); + signal cyc : std_logic; + + -- S/G adapter signals + signal sipo_sh_in : std_logic; + signal sipo_clr : std_logic; + signal sipo_full : std_logic; + + + signal piso_sh_out : std_logic; + signal piso_ld : std_logic; + signal piso_empty : std_logic; + signal piso_am_empty :std_logic; + signal piso_full : std_logic; + signal ld : std_logic; + + signal get_adr : std_logic; + signal B_STB : std_logic; + signal ALLRDY_STROBED : std_logic; + + component sipo_flag is + generic(g_width_IN : natural := 16; g_width_OUT : natural := 32); + port( + clk_i : in std_logic; + nRst_i : in std_logic; + + d_i : in std_logic_vector(g_width_IN-1 downto 0); + en_i : in std_logic; + clr_i : in std_logic; + + q_o : out std_logic_vector(g_width_OUT-1 downto 0); + full_o : out std_logic + + ); + end component; + + component piso_flag is +generic(g_width_IN : natural := 16; g_width_OUT : natural := 32); + port( + clk_i : in std_logic; + nRst_i : in std_logic; + + d_i : in std_logic_vector(g_width_IN-1 downto 0); + en_i : in std_logic; + ld_i : in std_logic; + + q_o : out std_logic_vector(g_width_OUT-1 downto 0); + + full_o : out std_logic; + almost_empty_o : out std_logic; + empty_o : out std_logic + +); +end component; + +begin + +assert not (g_dat_width_A = g_dat_width_B) report "WB streaming adapter superfluous, IO data widths are identical." severity error; + +--------------------------------------------------------------------------------------------------------------------------------- +PIPELINED: if(g_pipeline > 0) GENERATE + +A_LESSER_B: if(c_dat_w_min = g_dat_width_A) GENERATE + + gather : sipo_flag -- MA ->-> => MB + generic map(g_width_IN => c_dat_w_min, g_width_OUT => c_dat_w_max) + port map( + clk_i => clk_i, + nRst_i => nRSt_i, + + d_i => sipo_d, + en_i => sipo_sh_in, + clr_i => sipo_clr, + + q_o => sipo_q, + full_o => sipo_full + ); + + --for(i + + A_DAT_o <= (others => '0'); + A_ERR_o <= B_ERR_i; + A_RTY_o <= B_RTY_i; + + B_WE_o <= A_WE_i; + + A_STALL_o <= '1' when sipo_full ='1' AND B_STALL_i = '1' + else '0'; + + sipo_sh_in <= '1' when (NOT(sipo_full = '1' AND B_STALL_i = '1') AND A_STB_i = '1') + else '0'; + + B_CYC_o <= '1' when (A_CYC_i = '1' OR sipo_full= '1') + else '0'; + + + + + B_STB_o <= B_STB; + B_STB <= sipo_full AND NOT ALLRDY_STROBED; + + sipo_d <= A_DAT_i; + B_DAT_o <= sipo_q; + + process (clk_i) + begin + if (clk_i'event and clk_i = '1') then + if(nRSt_i = '0') then + + A_ACK_o <= '0'; + ALLRDY_STROBED <= '0'; + + else + + + if(sipo_full = '1') then + if(B_STALL_i = '0') then + ALLRDY_STROBED <= '1'; + end if; + else + ALLRDY_STROBED <= '0'; + end if; + + ------- TODO + if(A_STB_i = '1' AND NOT (sipo_full ='1' AND B_STALL_i = '1')) then + A_ACK_o <= '1'; + else + A_ACK_o <= '0'; + end if; + + end if; + end if; + end process; + + END GENERATE; + + --scatter +A_GREATER_B: if(c_dat_w_max = g_dat_width_A) GENERATE + + + scatter : piso_flag -- SB => ->-> SA + generic map(g_width_IN => c_dat_w_max, g_width_OUT => c_dat_w_min) + port map( + clk_i => clk_i, + nRst_i => nRSt_i, + + d_i => piso_d, + en_i => piso_sh_out, + ld_i => piso_ld, + + q_o => piso_q, + full_o => piso_full, + almost_empty_o => piso_am_empty, + empty_o => piso_empty + ); + + A_DAT_o <= (others => '0'); + piso_d <= A_DAT_i; + B_DAT_o <= piso_q; + A_ERR_o <= B_ERR_i; + A_RTY_o <= B_RTY_i; + B_WE_o <= A_WE_i; + + piso_ld <= '1' when A_STB_i = '1' AND (piso_empty = '1' OR (piso_am_empty ='1' AND B_STALL_i = '0')) + else '0'; + + piso_sh_out <= '1' when B_STALL_i = '0' AND piso_empty = '0' + else '0'; + + B_CYC_o <= '1' when (A_CYC_i = '1' OR piso_empty = '0') + else '0'; + + + B_STB_o <= '1' when (piso_empty = '0') + else '0'; + + A_STALL_o <= '1' when NOT (piso_empty = '1' OR (piso_am_empty ='1' AND B_STALL_i = '0')) + else '0'; + + + process (clk_i) + begin + if (clk_i'event and clk_i = '1') then + if(nRSt_i = '0') then + A_ACK_o <= '0'; + else + if(A_STB_i = '1' AND (piso_empty = '1' OR (piso_am_empty ='1' AND B_STALL_i = '0') )) then + A_ACK_o <= '1'; + else + A_ACK_o <= '0'; + end if; + end if; + end if; + end process; + end GENERATE; -- A_width < BA_width +end GENERATE; --pipeline A-B +end architecture; diff --git a/hdl/EB_SPEC_Test/alt_FIFO_am_full_flag.vhd b/hdl/EB_SPEC_Test/alt_FIFO_am_full_flag.vhd new file mode 100644 index 0000000000000000000000000000000000000000..282ac0a25454188b260d1da5ce4c5f586d42b67c --- /dev/null +++ b/hdl/EB_SPEC_Test/alt_FIFO_am_full_flag.vhd @@ -0,0 +1,244 @@ +--! @file alt_FIFO_am_full_flag.vhd +--! @brief altera FIFO +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + +-- megafunction wizard: %FIFO% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: scfifo + +-- ============================================================ +-- File Name: alt_FIFO_am_full_flag.vhd +-- Megafunction Name(s): +-- scfifo +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 10.1 Build 153 11/29/2010 SJ Full Version +-- ************************************************************ + + +--Copyright (C) 1991-2010 Altera Corporation +--Your use of Altera Corporation's design tools, logic functions +--and other software and tools, and its AMPP partner logic +--functions, and any output files from any of the foregoing +--(including device programming or simulation files), and any +--associated documentation or information are expressly subject +--to the terms and conditions of the Altera Program License +--Subscription Agreement, Altera MegaCore Function License +--Agreement, or other applicable license agreement, including, +--without limitation, that your use is for the sole purpose of +--programming logic devices manufactured by Altera and sold by +--Altera or its authorized distributors. Please refer to the +--applicable agreement for further details. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY alt_FIFO_am_full_flag IS + PORT + ( + clock : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (31 DOWNTO 0); + rdreq : IN STD_LOGIC ; + sclr : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + almost_empty : OUT STD_LOGIC ; + almost_full : OUT STD_LOGIC ; + empty : OUT STD_LOGIC ; + full : OUT STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + usedw : OUT STD_LOGIC_VECTOR (3 DOWNTO 0) + ); +END alt_FIFO_am_full_flag; + + +ARCHITECTURE SYN OF alt_fifo_am_full_flag IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (3 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC_VECTOR (31 DOWNTO 0); + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + + + + COMPONENT scfifo + GENERIC ( + add_ram_output_register : STRING; + almost_empty_value : NATURAL; + almost_full_value : NATURAL; + intended_device_family : STRING; + lpm_numwords : NATURAL; + lpm_showahead : STRING; + lpm_type : STRING; + lpm_width : NATURAL; + lpm_widthu : NATURAL; + overflow_checking : STRING; + underflow_checking : STRING; + use_eab : STRING + ); + PORT ( + clock : IN STD_LOGIC ; + sclr : IN STD_LOGIC ; + usedw : OUT STD_LOGIC_VECTOR (3 DOWNTO 0); + empty : OUT STD_LOGIC ; + full : OUT STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + wrreq : IN STD_LOGIC ; + almost_empty : OUT STD_LOGIC ; + almost_full : OUT STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (31 DOWNTO 0); + rdreq : IN STD_LOGIC + ); + END COMPONENT; + +BEGIN + usedw <= sub_wire0(3 DOWNTO 0); + empty <= sub_wire1; + full <= sub_wire2; + q <= sub_wire3(31 DOWNTO 0); + almost_empty <= sub_wire4; + almost_full <= sub_wire5; + + scfifo_component : scfifo + GENERIC MAP ( + add_ram_output_register => "OFF", + almost_empty_value => 1, + almost_full_value => 11, + intended_device_family => "Arria GX", + lpm_numwords => 16, + lpm_showahead => "ON", + lpm_type => "scfifo", + lpm_width => 32, + lpm_widthu => 4, + overflow_checking => "ON", + underflow_checking => "ON", + use_eab => "ON" + ) + PORT MAP ( + clock => clock, + sclr => sclr, + wrreq => wrreq, + data => data, + rdreq => rdreq, + usedw => sub_wire0, + empty => sub_wire1, + full => sub_wire2, + q => sub_wire3, + almost_empty => sub_wire4, + almost_full => sub_wire5 + ); + + + +END SYN; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: AlmostEmpty NUMERIC "1" +-- Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "1" +-- Retrieval info: PRIVATE: AlmostFull NUMERIC "1" +-- Retrieval info: PRIVATE: AlmostFullThr NUMERIC "11" +-- Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0" +-- Retrieval info: PRIVATE: Clock NUMERIC "0" +-- Retrieval info: PRIVATE: Depth NUMERIC "16" +-- Retrieval info: PRIVATE: Empty NUMERIC "1" +-- Retrieval info: PRIVATE: Full NUMERIC "1" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Arria GX" +-- Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0" +-- Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0" +-- Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0" +-- Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0" +-- Retrieval info: PRIVATE: Optimize NUMERIC "0" +-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0" +-- Retrieval info: PRIVATE: UsedW NUMERIC "1" +-- Retrieval info: PRIVATE: Width NUMERIC "32" +-- Retrieval info: PRIVATE: dc_aclr NUMERIC "0" +-- Retrieval info: PRIVATE: diff_widths NUMERIC "0" +-- Retrieval info: PRIVATE: msb_usedw NUMERIC "0" +-- Retrieval info: PRIVATE: output_width NUMERIC "32" +-- Retrieval info: PRIVATE: rsEmpty NUMERIC "1" +-- Retrieval info: PRIVATE: rsFull NUMERIC "0" +-- Retrieval info: PRIVATE: rsUsedW NUMERIC "0" +-- Retrieval info: PRIVATE: sc_aclr NUMERIC "0" +-- Retrieval info: PRIVATE: sc_sclr NUMERIC "1" +-- Retrieval info: PRIVATE: wsEmpty NUMERIC "0" +-- Retrieval info: PRIVATE: wsFull NUMERIC "1" +-- Retrieval info: PRIVATE: wsUsedW NUMERIC "0" +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF" +-- Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "1" +-- Retrieval info: CONSTANT: ALMOST_FULL_VALUE NUMERIC "11" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Arria GX" +-- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "16" +-- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo" +-- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32" +-- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "4" +-- Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON" +-- Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON" +-- Retrieval info: CONSTANT: USE_EAB STRING "ON" +-- Retrieval info: USED_PORT: almost_empty 0 0 0 0 OUTPUT NODEFVAL "almost_empty" +-- Retrieval info: USED_PORT: almost_full 0 0 0 0 OUTPUT NODEFVAL "almost_full" +-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock" +-- Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL "data[31..0]" +-- Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty" +-- Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full" +-- Retrieval info: USED_PORT: q 0 0 32 0 OUTPUT NODEFVAL "q[31..0]" +-- Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq" +-- Retrieval info: USED_PORT: sclr 0 0 0 0 INPUT NODEFVAL "sclr" +-- Retrieval info: USED_PORT: usedw 0 0 4 0 OUTPUT NODEFVAL "usedw[3..0]" +-- Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq" +-- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0 +-- Retrieval info: CONNECT: @data 0 0 32 0 data 0 0 32 0 +-- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 +-- Retrieval info: CONNECT: @sclr 0 0 0 0 sclr 0 0 0 0 +-- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 +-- Retrieval info: CONNECT: almost_empty 0 0 0 0 @almost_empty 0 0 0 0 +-- Retrieval info: CONNECT: almost_full 0 0 0 0 @almost_full 0 0 0 0 +-- Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0 +-- Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0 +-- Retrieval info: CONNECT: q 0 0 32 0 @q 0 0 32 0 +-- Retrieval info: CONNECT: usedw 0 0 4 0 @usedw 0 0 4 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL alt_FIFO_am_full_flag.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL alt_FIFO_am_full_flag.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL alt_FIFO_am_full_flag.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL alt_FIFO_am_full_flag.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL alt_FIFO_am_full_flag_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/hdl/EB_SPEC_Test/eb_config_new.vhd b/hdl/EB_SPEC_Test/eb_config_new.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fb398bf66133524be42e1b727fb0dbd78791b9ec --- /dev/null +++ b/hdl/EB_SPEC_Test/eb_config_new.vhd @@ -0,0 +1,195 @@ +--! @file EB_config.vhd +--! @brief EtherBone config space memory +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +--------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.wb32_package.all; + +entity eb_config is + port( + clk_i : in std_logic; --clock + nRST_i : in std_logic; + status_i : in std_logic; + status_en : in std_logic; + status_clr : in std_logic; + + my_mac_o : out std_logic_vector(6*8-1 downto 0); + my_ip_o : out std_logic_vector(4*8-1 downto 0); + my_port_o : out std_logic_vector(2*8-1 downto 0); + + local_slave_o : out wb32_slave_out; + local_slave_i : in wb32_slave_in; --! local Wishbone master lines + + eb_slave_o : out wb32_slave_out; --! EB Wishbone slave lines + eb_slave_i : in wb32_slave_in + ); +end eb_config; + + +architecture behavioral of eb_config is + +subtype dword is std_logic_vector(31 downto 0); +type mem is array (0 to 2) of dword ; +signal my_mem : mem; + + + +signal eb_adr : natural; +signal local_adr : natural; +signal local_write_reg : std_logic_vector(31 downto 0); + + +signal status_reg : std_logic_vector(63 downto 0); +signal p_auto_cfg : std_logic_vector(63 downto 0); + +signal my_mac : std_logic_vector(47 downto 0); +signal my_ip : std_logic_vector(31 downto 0); + +constant c_my_default_ip : std_logic_vector(31 downto 0) := x"C0A80064"; +constant c_my_default_mac : std_logic_vector(47 downto 0) := x"D15EA5EDBEEF"; + + +begin + + + + +eb_adr <= to_integer(unsigned(eb_slave_i.ADR(7 downto 0))); +local_adr <= to_integer(unsigned(local_slave_i.ADR(7 downto 0))); + +my_mac_o <= my_mac; +my_ip_o <= my_ip; + +local_slave_o.STALL <= eb_slave_i.CYC; + + + +eb_if : process (clk_i) + begin + if (clk_i'event and clk_i = '1') then + if(nRSt_i = '0') then + + + + eb_slave_o <= ( + ACK => '0', + ERR => '0', + RTY => '0', + STALL => '0', + DAT => (others => '0')); + + local_slave_o.ACK <= '0'; + local_slave_o.ERR <= '0'; + local_slave_o.RTY <= '0'; + local_slave_o.DAT <= (others => '0'); + + my_ip <= c_my_default_ip; + my_mac <= c_my_default_mac; + p_auto_cfg <= (others => '0'); + + else + eb_slave_o.ACK <= eb_slave_i.CYC AND eb_slave_i.STB; + + if(eb_slave_i.STB = '1' AND eb_slave_i.CYC = '1') then + + if(eb_slave_i.WE ='1') then + case eb_adr is + when 0 => null; + when 16 => my_mac(47 downto 16) <= eb_slave_i.DAT(31 downto 0); + when 20 => my_mac(15 downto 0) <= eb_slave_i.DAT(31 downto 16); + when 24 => my_ip <= eb_slave_i.DAT; + when others => null; + end case; + else + case eb_adr is + when 0 => eb_slave_o.DAT <= status_reg(63 downto 32); + when 4 => eb_slave_o.DAT <= status_reg(31 downto 0); + when 8 => eb_slave_o.DAT <= p_auto_cfg(63 downto 32); + when 12 => eb_slave_o.DAT <= p_auto_cfg(31 downto 0); + when 16 => eb_slave_o.DAT <= my_mac(47 downto 16); + when 20 => eb_slave_o.DAT <= (my_mac(15 downto 0) & std_logic_vector(to_unsigned(0, 16))); + when 24 => eb_slave_o.DAT <= my_ip; + + when others => eb_slave_o.DAT <= status_reg(63 downto 32); + end case; + end if; + end if; + + if(local_slave_i.STB = '1' AND local_slave_i.CYC = '1' AND eb_slave_i.CYC = '0') then + local_slave_o.ACK <= '1'; + if(local_slave_i.WE ='1') then + local_write_reg <= local_slave_i.DAT; + + case local_adr is + when 8 => p_auto_cfg(63 downto 32) <= local_write_reg; + when 12 => p_auto_cfg(31 downto 0) <= local_write_reg; + when 16 => my_mac(47 downto 16) <= local_write_reg(31 downto 0); + when 20 => my_mac(15 downto 0) <= local_write_reg(31 downto 16); + when 24 => my_ip <= local_write_reg; + when others => null; + end case; + else + case local_adr is + when 0 => local_slave_o.DAT <= status_reg(63 downto 32); + when 4 => local_slave_o.DAT <= status_reg(31 downto 0); + when 8 => local_slave_o.DAT <= p_auto_cfg(63 downto 32); + when 12 => local_slave_o.DAT <= p_auto_cfg(31 downto 0); + when 16 => local_slave_o.DAT <= my_mac(47 downto 16); + when 20 => local_slave_o.DAT <= my_mac(15 downto 0) & std_logic_vector(to_unsigned(0, 16)); + when 24 => local_slave_o.DAT <= my_ip; + + when others => local_slave_o.DAT <= status_reg(63 downto 32); + end case; + end if; + end if; + end if; + + end if; + +end process; + + + + +status_reg_sh : process(clk_i) +begin + if (clk_i'event and clk_i = '1') then + if(nRSt_i = '0') then + status_reg <= (others => '1'); + else + if(status_clr = '1') then + status_reg <= (others => '1'); + elsif(status_en = '1') then + status_reg <= status_reg(status_reg'left-1 downto 0) & status_i; + end if; + end if; + end if; +end process; + +end behavioral; diff --git a/hdl/EB_SPEC_Test/piso_flag.vhd b/hdl/EB_SPEC_Test/piso_flag.vhd new file mode 100644 index 0000000000000000000000000000000000000000..115c86c85414c157fb506aa86a838aa5d34ad8cf --- /dev/null +++ b/hdl/EB_SPEC_Test/piso_flag.vhd @@ -0,0 +1,96 @@ +--! @file piso_flag.vhd +--! @brief Parallel-In-Serial-Out shiftregister with flags +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +-------------------------------------------------------------------------------- + + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity piso_flag is +generic(g_width_IN : natural := 16; g_width_OUT : natural := 32); +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + d_i : in std_logic_vector(g_width_IN-1 downto 0); + en_i : in std_logic; + ld_i : in std_logic; + + q_o : out std_logic_vector(g_width_OUT-1 downto 0); + + full_o : out std_logic; + almost_empty_o : out std_logic; + empty_o : out std_logic + +); +end piso_flag; + + + + +architecture behavioral of piso_flag is + +signal sh_cnt : unsigned(8 downto 0); +alias empty : std_logic is sh_cnt(sh_cnt'LEFT); + +signal sh_reg : std_logic_vector(g_width_in -1 downto 0); +constant zero_insert : std_logic_vector(g_width_out-1 downto 0) := (others => '0'); +signal full : std_logic; + + +begin +almost_empty_o <= '1' when sh_cnt = to_unsigned(0, 9) + else '0'; +q_o <= sh_reg(sh_reg'left downto sh_reg'length-q_o'length); +empty_o <= empty; +full_o <= full; + + -- Your VHDL code defining the model goes here + process (clk_i) + begin + if (clk_i'event and clk_i = '1') then + if(nRSt_i = '0') then + full <= '0'; + sh_cnt <= (others => '1'); + + else + if(ld_i = '1' AND full = '0') then + full <= '1'; + sh_cnt <= to_unsigned((g_width_IN/g_width_OUT)-1,9); + sh_reg <= d_i; + elsif(en_i = '1' AND empty = '0') then + full <= '0'; + sh_cnt <= sh_cnt-1; + sh_reg <= sh_reg(g_width_in - g_width_out -1 downto 0) & zero_insert; + end if; + end if; + end if; + end process; + +end behavioral; diff --git a/hdl/EB_SPEC_Test/sipo_flag.vhd b/hdl/EB_SPEC_Test/sipo_flag.vhd new file mode 100644 index 0000000000000000000000000000000000000000..cbb59942e4a2190810b4c36c2ba36760beee3a82 --- /dev/null +++ b/hdl/EB_SPEC_Test/sipo_flag.vhd @@ -0,0 +1,96 @@ +--! @file sipo_flag.vhd +--! @brief Serial-In-Parallel-Out shiftregister with flags +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +-------------------------------------------------------------------------------- + +---! Standard library +library IEEE; +--! Standard packages +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.vhdl_2008_workaround_pkg.all; + +entity sipo_flag is +generic(g_width_IN : natural := 8; g_width_OUT : natural := 32); +port( + clk_i : in std_logic; + nRst_i : in std_logic; + + d_i : in std_logic_vector(g_width_IN-1 downto 0); + en_i : in std_logic; + clr_i : in std_logic; + + q_o : out std_logic_vector(g_width_OUT-1 downto 0); + full_o : out std_logic; + empty_o : out std_logic +); +end sipo_flag; + + + + +architecture behavioral of sipo_flag is + +signal sh_reg : std_logic_vector(g_width_OUT-1 downto 0); -- length + 1 for flag +signal full : std_logic; +signal empty : std_logic; + +constant check_full : natural := maximum(0, g_width_OUT/g_width_IN-1); +signal cnt : unsigned(ld(g_width_OUT/g_width_IN) downto 0); + +begin + +q_o <= sh_reg(sh_reg'left downto 0); +full_o <= full; +empty_o <= empty; + + -- Your VHDL code defining the model goes here + process (clk_i) + begin + if (clk_i'event and clk_i = '1') then + if(nRSt_i = '0' OR clr_i = '1') then + sh_reg <= (others => '0'); + full <= '0'; + empty <= '1'; + cnt <= (others => '0'); + else + if(en_i = '1') then + sh_reg <= sh_reg(g_width_OUT-1 - g_width_IN downto 0) & d_i; + empty <= '0'; + full <= '0'; + cnt <= cnt +1; + + if(cnt = check_full) then -- writing to last space + full <= '1'; + cnt <= (others => '0'); + end if; + + end if; + end if; + end if; + end process; + +end behavioral; diff --git a/hdl/EB_SPEC_Test/vhdl_2008_workaround_pkg.vhd b/hdl/EB_SPEC_Test/vhdl_2008_workaround_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a46bc6a7990344af6724df39cf557cbce46b3b65 --- /dev/null +++ b/hdl/EB_SPEC_Test/vhdl_2008_workaround_pkg.vhd @@ -0,0 +1,113 @@ +--! @file vhdl_2008_workaround_pkg.vhd +--! @brief VHDL 2008 alike functions +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package vhdl_2008_workaround_pkg is + + + +function minimum(A : integer; B : integer) +return integer; + +function maximum(A : integer; B : integer) +return integer; + +function ld(X : natural) +return natural; + +function sign(X : integer) +return integer; + +end vhdl_2008_workaround_pkg; + + package body vhdl_2008_workaround_pkg is + +function minimum(A : integer; B : integer) +return integer is + variable tmp : integer; + begin + if(A < B) then + tmp := A; + else + tmp := B; + end if; + return tmp; +end function minimum; + +function maximum(A : integer; B : integer) +return integer is + variable tmp : integer; + begin + if(A > B) then + tmp := A; + else + tmp := B; + end if; + + return tmp; +end function maximum; + +function ld(X : natural) +return natural is + variable tmp : natural := 32; + variable search : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(X, 32)); + variable found : std_logic := '0'; + begin + if(X = 0) then + tmp := 1; + else + while(tmp > 0 AND found = '0') loop + if(found = '0') then + tmp := tmp -1; + end if; + found := search(tmp); + + end loop; + end if; + return tmp; +end function ld; + +function sign(X : integer) +return integer is + variable tmp : integer := 0; + begin + if(X = 0) then + tmp := 0; + elsif(X > 0) then + tmp := 1; + else + tmp := -1; + end if; + return tmp; +end function sign; + + + +end package body; diff --git a/hdl/EB_SPEC_Test/wishbone_package16.vhd b/hdl/EB_SPEC_Test/wishbone_package16.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2893fc1db24e604d4874fef5e7b9cd6fa3bfad4c --- /dev/null +++ b/hdl/EB_SPEC_Test/wishbone_package16.vhd @@ -0,0 +1,109 @@ +--! @file wishbone_package16.vhd +--! @brief 16b wide WB records +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package wb16_package is + + constant wishbone_address_width : integer := 32; + constant wishbone_data_width : integer := 16; + + subtype wishbone_address is + std_logic_vector(wishbone_address_width-1 downto 0); + subtype wishbone_data is + std_logic_vector(wishbone_data_width-1 downto 0); + subtype wishbone_byte_select is + std_logic_vector((wishbone_data_width/8)-1 downto 0); + subtype wishbone_cycle_type is + std_logic_vector(2 downto 0); + subtype wishbone_burst_type is + std_logic_vector(1 downto 0); + + -- A B.4 Wishbone pipelined master + -- Pipelined wishbone is always LOCKed during CYC (else ACKs would get lost) + type wb16_master_out is record + CYC : std_logic; + STB : std_logic; + ADR : wishbone_address; + SEL : wishbone_byte_select; + WE : std_logic; + DAT : wishbone_data; + end record wb16_master_out; + subtype wb16_slave_in is wb16_master_out; + + type wb16_slave_out is record + ACK : std_logic; + ERR : std_logic; + RTY : std_logic; + STALL : std_logic; + DAT : wishbone_data; + end record wb16_slave_out; + subtype wb16_master_in is wb16_slave_out; + + type wishbone_v3_master_out is record + CYC : std_logic; + STB : std_logic; + ADR : wishbone_address; + SEL : wishbone_byte_select; + WE : std_logic; + LOCK : std_logic; + DAT : wishbone_data; + CTI : wishbone_cycle_type; + BTE : wishbone_burst_type; + end record wishbone_v3_master_out; + subtype wishbone_v3_slave_in is wishbone_v3_master_out; + + type wishbone_v3_slave_out is record + ACK : std_logic; + ERR : std_logic; + RTY : std_logic; + DAT : wishbone_data; + end record wishbone_v3_slave_out; + subtype wishbone_v3_master_in is wishbone_v3_slave_out; + + type wb16_master_out_vector is array (natural range <>) of wb16_master_out; + type wb16_slave_out_vector is array (natural range <>) of wb16_slave_out; + subtype wb16_slave_in_vector is wb16_master_out_vector; + subtype wb16_master_in_vector is wb16_slave_out_vector; + + type wishbone_v3_master_out_vector is array (natural range <>) of wishbone_v3_master_out; + type wishbone_v3_slave_out_vector is array (natural range <>) of wishbone_v3_slave_out; + subtype wishbone_v3_slave_in_vector is wishbone_v3_master_out_vector; + subtype wishbone_v3_master_in_vector is wishbone_v3_slave_out_vector; + + type wishbone_address_vector is array (natural range <>) of wishbone_address; + type wishbone_data_vector is array (natural range <>) of wishbone_data; + + + + + end wb16_package; + + package body wb16_package is + end package body; diff --git a/hdl/EB_SPEC_Test/wishbone_package32.vhd b/hdl/EB_SPEC_Test/wishbone_package32.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b7050888ab36203530e5ed0c9e638844da55a362 --- /dev/null +++ b/hdl/EB_SPEC_Test/wishbone_package32.vhd @@ -0,0 +1,219 @@ +--! @file wishbone_package32.vhd +--! @brief 32b wide WB records +--! +--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH +--! +--! Important details about its implementation +--! should go in these comments. +--! +--! @author Mathias Kreider <m.kreider@gsi.de> +--! +--! @bug No know bugs. +--! +-------------------------------------------------------------------------------- +--! This library is free software; you can redistribute it and/or +--! modify it under the terms of the GNU Lesser General Public +--! License as published by the Free Software Foundation; either +--! version 3 of the License, or (at your option) any later version. +--! +--! This library is distributed in the hope that it will be useful, +--! but WITHOUT ANY WARRANTY; without even the implied warranty of +--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +--! Lesser General Public License for more details. +--! +--! You should have received a copy of the GNU Lesser General Public +--! License along with this library. If not, see <http://www.gnu.org/licenses/>. +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package wb32_package is + + constant wishbone_address_width : integer := 32; + constant wishbone_data_width : integer := 32; + + subtype wishbone_address is + std_logic_vector(wishbone_address_width-1 downto 0); + subtype wishbone_data is + std_logic_vector(wishbone_data_width-1 downto 0); + subtype wishbone_byte_select is + std_logic_vector((wishbone_address_width/8)-1 downto 0); + subtype wishbone_cycle_type is + std_logic_vector(2 downto 0); + subtype wishbone_burst_type is + std_logic_vector(1 downto 0); + + -- A B.4 Wishbone pipelined master + -- Pipelined wishbone is always LOCKed during CYC (else ACKs would get lost) + type wb32_master_out is record + CYC : std_logic; + STB : std_logic; + ADR : wishbone_address; + SEL : wishbone_byte_select; + WE : std_logic; + DAT : wishbone_data; + end record wb32_master_out; + subtype wb32_slave_in is wb32_master_out; + + type wb32_slave_out is record + ACK : std_logic; + ERR : std_logic; + RTY : std_logic; + STALL : std_logic; + DAT : wishbone_data; + end record wb32_slave_out; + subtype wb32_master_in is wb32_slave_out; + + type wishbone_v3_master_out is record + CYC : std_logic; + STB : std_logic; + ADR : wishbone_address; + SEL : wishbone_byte_select; + WE : std_logic; + LOCK : std_logic; + DAT : wishbone_data; + CTI : wishbone_cycle_type; + BTE : wishbone_burst_type; + end record wishbone_v3_master_out; + subtype wishbone_v3_slave_in is wishbone_v3_master_out; + + type wishbone_v3_slave_out is record + ACK : std_logic; + ERR : std_logic; + RTY : std_logic; + DAT : wishbone_data; + end record wishbone_v3_slave_out; + subtype wishbone_v3_master_in is wishbone_v3_slave_out; + + type wb32_master_out_vector is array (natural range <>) of wb32_master_out; + type wb32_slave_out_vector is array (natural range <>) of wb32_slave_out; + subtype wb32_slave_in_vector is wb32_master_out_vector; + subtype wb32_master_in_vector is wb32_slave_out_vector; + + type wishbone_v3_master_out_vector is array (natural range <>) of wishbone_v3_master_out; + type wishbone_v3_slave_out_vector is array (natural range <>) of wishbone_v3_slave_out; + subtype wishbone_v3_slave_in_vector is wishbone_v3_master_out_vector; + subtype wishbone_v3_master_in_vector is wishbone_v3_slave_out_vector; + + type wishbone_address_vector is array (natural range <>) of wishbone_address; + type wishbone_data_vector is array (natural range <>) of wishbone_data; + + function TO_STD_LOGIC_VECTOR(X : wb32_slave_out) +return std_logic_vector; + +function TO_wb32_slave_out(X : std_logic_vector) +return wb32_slave_out; + + function TO_STD_LOGIC_VECTOR(X : wb32_master_out) +return std_logic_vector; + +function TO_wb32_master_out(X : std_logic_vector) +return wb32_master_out; + + + + -- function TO_STD_LOGIC_VECTOR(X : wb32_master_in) +-- return std_logic_vector; + +function TO_wb32_master_in(X : std_logic_vector) +return wb32_master_in; + + -- function TO_STD_LOGIC_VECTOR(X : wb32_slave_in) +-- return std_logic_vector; + +function TO_wb32_slave_in(X : std_logic_vector) +return wb32_slave_in; + + end wb32_package; + + package body wb32_package is + + function TO_STD_LOGIC_VECTOR(X : wb32_slave_out) +return std_logic_vector is + variable tmp : std_logic_vector(35 downto 0) := (others => '0'); + begin + tmp := X.ACK & X.ERR & X.RTY & X.STALL & X.DAT; + return tmp; +end function TO_STD_LOGIC_VECTOR; + +function TO_wb32_slave_out(X : std_logic_vector) +return wb32_slave_out is + variable tmp : wb32_slave_out; + begin + tmp.ACK := X(35); + tmp.ERR := X(34); + tmp.RTY := X(33); + tmp.STALL := X(32); + tmp.DAT := X(31 downto 0); + + return tmp; +end function TO_wb32_slave_out; + + + function TO_STD_LOGIC_VECTOR(X : wb32_master_out) +return std_logic_vector is + variable tmp : std_logic_vector(70 downto 0) := (others => '0'); + begin + tmp := X.CYC & X.STB & X.ADR & X.SEL & X.WE & X.DAT; + return tmp; +end function TO_STD_LOGIC_VECTOR; + +function TO_wb32_master_out(X : std_logic_vector) +return wb32_master_out is + variable tmp : wb32_master_out; + begin + tmp.CYC := X(70); + tmp.STB := X(69); + tmp.ADR := X(68 downto 37); + tmp.SEL := X(36 downto 33); + tmp.WE := X(32); + tmp.DAT := X(31 downto 0); + return tmp; +end function TO_wb32_master_out; + + -- function TO_STD_LOGIC_VECTOR(X : wb32_master_in) +-- return std_logic_vector is + -- variable tmp : std_logic_vector(35 downto 0) := (others => '0'); + -- begin + -- tmp := X.ACK & X.ERR & X.RTY & X.STALL & X.DAT; + -- return tmp; +-- end function TO_STD_LOGIC_VECTOR; + +function TO_wb32_master_in(X : std_logic_vector) +return wb32_master_in is + variable tmp : wb32_master_in; + begin + tmp.ACK := X(35); + tmp.ERR := X(34); + tmp.RTY := X(33); + tmp.STALL := X(32); + tmp.DAT := X(31 downto 0); + + return tmp; +end function TO_wb32_master_in; + + + -- function TO_STD_LOGIC_VECTOR(X : wb32_slave_in) +-- return std_logic_vector is + -- variable tmp : std_logic_vector(70 downto 0) := (others => '0'); + -- begin + -- tmp := X.CYC & X.STB & X.ADR & X.SEL & X.WE & X.DAT; + -- return tmp; +-- end function TO_STD_LOGIC_VECTOR; + +function TO_wb32_slave_in(X : std_logic_vector) +return wb32_slave_in is + variable tmp : wb32_slave_in; + begin + tmp.CYC := X(70); + tmp.STB := X(69); + tmp.ADR := X(68 downto 37); + tmp.SEL := X(36 downto 33); + tmp.WE := X(32); + tmp.DAT := X(31 downto 0); + return tmp; +end function TO_wb32_slave_in; + +end package body; diff --git a/hdl/EB_SPEC_Test/wishbone_pkg.vhd b/hdl/EB_SPEC_Test/wishbone_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8985a1ef49dc8ae4c7b5854019abf15b99c64194 --- /dev/null +++ b/hdl/EB_SPEC_Test/wishbone_pkg.vhd @@ -0,0 +1,497 @@ +library ieee; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; + +package wishbone_pkg is + + constant c_wishbone_address_width : integer := 32; + constant c_wishbone_data_width : integer := 32; + + subtype t_wishbone_address is + std_logic_vector(c_wishbone_address_width-1 downto 0); + subtype t_wishbone_data is + std_logic_vector(c_wishbone_data_width-1 downto 0); + subtype t_wishbone_byte_select is + std_logic_vector((c_wishbone_address_width/8)-1 downto 0); + subtype t_wishbone_cycle_type is + std_logic_vector(2 downto 0); + subtype t_wishbone_burst_type is + std_logic_vector(1 downto 0); + + type t_wishbone_interface_mode is (CLASSIC, PIPELINED); + type t_wishbone_address_granularity is (BYTE, WORD); + + type t_wishbone_master_out is record + cyc : std_logic; + stb : std_logic; + adr : t_wishbone_address; + sel : t_wishbone_byte_select; + we : std_logic; + dat : t_wishbone_data; + end record t_wishbone_master_out; + + subtype t_wishbone_slave_in is t_wishbone_master_out; + + type t_wishbone_slave_out is record + ack : std_logic; + err : std_logic; + rty : std_logic; + stall : std_logic; + int : std_logic; + dat : t_wishbone_data; + end record t_wishbone_slave_out; + subtype t_wishbone_master_in is t_wishbone_slave_out; + + subtype t_wishbone_device_descriptor is std_logic_vector(255 downto 0); + + + + type t_wishbone_address_array is array(integer range <>) of t_wishbone_address; + type t_wishbone_master_out_array is array (natural range <>) of t_wishbone_master_out; + type t_wishbone_slave_out_array is array (natural range <>) of t_wishbone_slave_out; + type t_wishbone_master_in_array is array (natural range <>) of t_wishbone_master_in; + type t_wishbone_slave_in_array is array (natural range <>) of t_wishbone_slave_in; + + + constant cc_dummy_address : std_logic_vector(c_wishbone_address_width-1 downto 0):= + (others => 'X'); + constant cc_dummy_data : std_logic_vector(c_wishbone_address_width-1 downto 0) := + (others => 'X'); + constant cc_dummy_sel : std_logic_vector(c_wishbone_data_width/8-1 downto 0) := + (others => 'X'); + constant cc_dummy_slave_in : t_wishbone_slave_in := + ('X', 'X', cc_dummy_address, cc_dummy_sel, 'X', cc_dummy_data); + constant cc_dummy_slave_out : t_wishbone_slave_out := + ('X', 'X', 'X', 'X', 'X', cc_dummy_data); + + +------------------------------------------------------------------------------ +-- Components declaration +------------------------------------------------------------------------------- + + component wb_slave_adapter + generic ( + g_master_use_struct : boolean; + g_master_mode : t_wishbone_interface_mode; + g_master_granularity : t_wishbone_address_granularity; + g_slave_use_struct : boolean; + g_slave_mode : t_wishbone_interface_mode; + g_slave_granularity : t_wishbone_address_granularity); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + sl_adr_i : in std_logic_vector(c_wishbone_address_width-1 downto 0) := cc_dummy_address; + sl_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0) := cc_dummy_data; + sl_sel_i : in std_logic_vector(c_wishbone_data_width/8-1 downto 0) := cc_dummy_sel; + sl_cyc_i : in std_logic := '0'; + sl_stb_i : in std_logic := '0'; + sl_we_i : in std_logic := '0'; + sl_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0); + sl_err_o : out std_logic; + sl_rty_o : out std_logic; + sl_ack_o : out std_logic; + sl_stall_o : out std_logic; + sl_int_o : out std_logic; + slave_i : in t_wishbone_slave_in := cc_dummy_slave_in; + slave_o : out t_wishbone_slave_out; + ma_adr_o : out std_logic_vector(c_wishbone_address_width-1 downto 0); + ma_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0); + ma_sel_o : out std_logic_vector(c_wishbone_data_width/8-1 downto 0); + ma_cyc_o : out std_logic; + ma_stb_o : out std_logic; + ma_we_o : out std_logic; + ma_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0) := cc_dummy_data; + ma_err_i : in std_logic := '0'; + ma_rty_i : in std_logic := '0'; + ma_ack_i : in std_logic := '0'; + ma_stall_i : in std_logic := '0'; + ma_int_i : in std_logic := '0'; + master_i : in t_wishbone_master_in := cc_dummy_slave_out; + master_o : out t_wishbone_master_out); + end component; + + component wb_async_bridge + generic ( + g_simulation : integer; + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_cpu_address_width : integer); + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + cpu_cs_n_i : in std_logic; + cpu_wr_n_i : in std_logic; + cpu_rd_n_i : in std_logic; + cpu_bs_n_i : in std_logic_vector(3 downto 0); + cpu_addr_i : in std_logic_vector(g_cpu_address_width-1 downto 0); + cpu_data_b : inout std_logic_vector(31 downto 0); + cpu_nwait_o : out std_logic; + wb_adr_o : out std_logic_vector(c_wishbone_address_width - 1 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_stb_o : out std_logic; + wb_we_o : out std_logic; + wb_sel_o : out std_logic_vector(3 downto 0); + wb_cyc_o : out std_logic; + wb_dat_i : in std_logic_vector (c_wishbone_data_width-1 downto 0); + wb_ack_i : in std_logic; + wb_stall_i : in std_logic := '0'); + end component; + + component xwb_async_bridge + generic ( + g_simulation : integer; + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_cpu_address_width : integer); + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + cpu_cs_n_i : in std_logic; + cpu_wr_n_i : in std_logic; + cpu_rd_n_i : in std_logic; + cpu_bs_n_i : in std_logic_vector(3 downto 0); + cpu_addr_i : in std_logic_vector(g_cpu_address_width-1 downto 0); + cpu_data_b : inout std_logic_vector(31 downto 0); + cpu_nwait_o : out std_logic; + master_o : out t_wishbone_master_out; + master_i : in t_wishbone_master_in); + end component; + + component xwb_bus_fanout + generic ( + g_num_outputs : natural; + g_bits_per_slave : integer; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_slave_interface_mode : t_wishbone_interface_mode := CLASSIC); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + master_i : in t_wishbone_master_in_array(0 to g_num_outputs-1); + master_o : out t_wishbone_master_out_array(0 to g_num_outputs-1)); + end component; + + component xwb_crossbar + generic ( + g_num_masters : integer; + g_num_slaves : integer; + g_registered : boolean); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in_array(g_num_masters-1 downto 0); + slave_o : out t_wishbone_slave_out_array(g_num_masters-1 downto 0); + master_i : in t_wishbone_master_in_array(g_num_slaves-1 downto 0); + master_o : out t_wishbone_master_out_array(g_num_slaves-1 downto 0); + cfg_address_i : in t_wishbone_address_array(g_num_slaves-1 downto 0); + cfg_mask_i : in t_wishbone_address_array(g_num_slaves-1 downto 0)); + end component; + + component xwb_dpram + generic ( + g_size : natural; + g_init_file : string := ""; + g_must_have_init_file : boolean := true; + g_slave1_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_slave2_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_slave1_granularity : t_wishbone_address_granularity := WORD; + g_slave2_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave1_i : in t_wishbone_slave_in; + slave1_o : out t_wishbone_slave_out; + slave2_i : in t_wishbone_slave_in; + slave2_o : out t_wishbone_slave_out); + end component; + + component wb_gpio_port + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_pins : natural range 1 to 256; + g_with_builtin_tristates : boolean := false); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + wb_sel_i : in std_logic_vector(c_wishbone_data_width/8-1 downto 0); + wb_cyc_i : in std_logic; + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_adr_i : in std_logic_vector(7 downto 0); + wb_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_ack_o : out std_logic; + wb_stall_o : out std_logic; + gpio_b : inout std_logic_vector(g_num_pins-1 downto 0); + gpio_out_o : out std_logic_vector(g_num_pins-1 downto 0); + gpio_in_i : in std_logic_vector(g_num_pins-1 downto 0); + gpio_oen_o : out std_logic_vector(g_num_pins-1 downto 0)); + end component; + + component xwb_gpio_port + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_pins : natural range 1 to 256; + g_with_builtin_tristates : boolean); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + gpio_b : inout std_logic_vector(g_num_pins-1 downto 0); + gpio_out_o : out std_logic_vector(g_num_pins-1 downto 0); + gpio_in_i : in std_logic_vector(g_num_pins-1 downto 0); + gpio_oen_o : out std_logic_vector(g_num_pins-1 downto 0)); + end component; + + component wb_i2c_master + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + wb_adr_i : in std_logic_vector(4 downto 0); + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_cyc_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_int_o : out std_logic; + wb_stall_o : out std_logic; + scl_pad_i : in std_logic; + scl_pad_o : out std_logic; + scl_padoen_o : out std_logic; + sda_pad_i : in std_logic; + sda_pad_o : out std_logic; + sda_padoen_o : out std_logic); + end component; + + component xwb_i2c_master + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + scl_pad_i : in std_logic; + scl_pad_o : out std_logic; + scl_padoen_o : out std_logic; + sda_pad_i : in std_logic; + sda_pad_o : out std_logic; + sda_padoen_o : out std_logic); + end component; + + component xwb_lm32 + generic ( + g_profile : string); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + irq_i : in std_logic_vector(31 downto 0); + dwb_o : out t_wishbone_master_out; + dwb_i : in t_wishbone_master_in; + iwb_o : out t_wishbone_master_out; + iwb_i : in t_wishbone_master_in); + end component; + + component wb_onewire_master + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_ports : integer; + g_ow_btp_normal : string := "1.0"; + g_ow_btp_overdrive : string := "5.0"); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(c_wishbone_data_width/8-1 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_adr_i : in std_logic_vector(2 downto 0); + wb_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_ack_o : out std_logic; + wb_int_o : out std_logic; + wb_stall_o : out std_logic; + owr_pwren_o : out std_logic_vector(g_num_ports -1 downto 0); + owr_en_o : out std_logic_vector(g_num_ports -1 downto 0); + owr_i : in std_logic_vector(g_num_ports -1 downto 0)); + end component; + + component xwb_onewire_master + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_ports : integer; + g_ow_btp_normal : string := "5.0"; + g_ow_btp_overdrive : string := "1.0"); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + owr_pwren_o : out std_logic_vector(g_num_ports -1 downto 0); + owr_en_o : out std_logic_vector(g_num_ports -1 downto 0); + owr_i : in std_logic_vector(g_num_ports -1 downto 0)); + end component; + + component wb_spi + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + wb_adr_i : in std_logic_vector(4 downto 0); + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_cyc_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_int_o : out std_logic; + wb_stall_o : out std_logic; + pad_cs_o : out std_logic_vector(7 downto 0); + pad_sclk_o : out std_logic; + pad_mosi_o : out std_logic; + pad_miso_i : in std_logic); + end component; + + component xwb_spi + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + pad_cs_o : out std_logic_vector(7 downto 0); + pad_sclk_o : out std_logic; + pad_mosi_o : out std_logic; + pad_miso_i : in std_logic); + end component; + + component wb_simple_uart + generic ( + g_with_virtual_uart : boolean := false; + g_with_physical_uart : boolean := true; + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + wb_adr_i : in std_logic_vector(4 downto 0); + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_stall_o : out std_logic; + uart_rxd_i : in std_logic := '1'; + uart_txd_o : out std_logic); + end component; + + component xwb_simple_uart + generic ( + g_with_virtual_uart : boolean := false; + g_with_physical_uart : boolean := true; + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + uart_rxd_i : in std_logic := '1'; + uart_txd_o : out std_logic); + end component; + + component wb_tics + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_period : integer); + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_adr_i : in std_logic_vector(3 downto 0); + wb_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(c_wishbone_data_width/8-1 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_stall_o : out std_logic); + end component; + + component xwb_tics + generic ( + g_interface_mode : t_wishbone_interface_mode := CLASSIC; + g_address_granularity : t_wishbone_address_granularity := WORD; + g_period : integer); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor); + end component; + + component wb_vic + generic ( + g_interface_mode : t_wishbone_interface_mode; + g_address_granularity : t_wishbone_address_granularity; + g_num_interrupts : natural); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + wb_adr_i : in std_logic_vector(c_wishbone_address_width-1 downto 0); + wb_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(c_wishbone_data_width/8-1 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_stall_o : out std_logic; + irqs_i : in std_logic_vector(g_num_interrupts-1 downto 0); + irq_master_o : out std_logic); + end component; + + component xwb_vic + generic ( + g_interface_mode : t_wishbone_interface_mode; + g_address_granularity : t_wishbone_address_granularity; + g_num_interrupts : natural); + port ( + clk_sys_i : in std_logic; + rst_n_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + irqs_i : in std_logic_vector(g_num_interrupts-1 downto 0); + irq_master_o : out std_logic); + end component; +end wishbone_pkg;