diff --git a/modules/common/Manifest.py b/modules/common/Manifest.py index ccf1c82b0c17a7dc93a6347b4d2e7b41a85bb8c1..9c368339be646ecb8a36828bb66039ddb20e89d2 100644 --- a/modules/common/Manifest.py +++ b/modules/common/Manifest.py @@ -32,4 +32,5 @@ files = [ "gc_dyn_extend_pulse.vhd", "gc_ds182x_interface.vhd", "gc_ds182x_readout.vhd", + "gc_sfp_i2c_adapter.vhd", ]; diff --git a/modules/common/gc_sfp_i2c_adapter.vhd b/modules/common/gc_sfp_i2c_adapter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..3c4a3086e76c313d0d9d882e4c372d96b0ae0cdd --- /dev/null +++ b/modules/common/gc_sfp_i2c_adapter.vhd @@ -0,0 +1,159 @@ +-------------------------------------------------------------------------------- +-- CERN BE-CO-HT +-- General Cores Library +-- https://www.ohwr.org/projects/general-cores +-------------------------------------------------------------------------------- +-- +-- unit name: gc_sfp_i2c_adapter +-- +-- description: A simple I2C adapter that emulates the SFP DDM and provides +-- access to the vendor id. Useful for when the SFP is not directly accessible +-- over I2C. +-- +-------------------------------------------------------------------------------- +-- Copyright CERN 2016-2019 +-------------------------------------------------------------------------------- +-- Copyright and related rights are licensed under the Solderpad Hardware +-- License, Version 2.0 (the "License"); you may not use this file except +-- in compliance with the License. You may obtain a copy of the License at +-- http://solderpad.org/licenses/SHL-2.0. +-- Unless required by applicable law or agreed to in writing, software, +-- hardware and materials distributed under this License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +-- or implied. See the License for the specific language governing permissions +-- and limitations under the License. +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.gencores_pkg.all; + +entity gc_sfp_i2c_adapter is + port ( + + -- Clock, reset ports + clk_i : in std_logic; + rst_n_i : in std_logic; + + -- I2C lines + scl_i : in std_logic; + sda_i : in std_logic; + sda_en_o : out std_logic; + + -- HIGH if both of the following are true: + -- 1. SFP is detected (plugged in) + -- 2. The part number has been successfully read after the SFP detection + sfp_det_valid_i : in std_logic; + -- 16 byte vendor Part Number (PN) + -- (ASCII encoded, first character byte in bits 127 downto 120) + sfp_data_i : in std_logic_vector (127 downto 0) + ); +end entity gc_sfp_i2c_adapter; + +architecture rtl of gc_sfp_i2c_adapter is + + ----------------------------------------------------------------------------- + -- Types + ----------------------------------------------------------------------------- + + -- 64-byte array representing the DDM serial ID area of the SFP management + type t_sfp_ddm_serial_id is array (0 to 63) of std_logic_vector(7 downto 0); + + ----------------------------------------------------------------------------- + -- Signals + ----------------------------------------------------------------------------- + + signal sfp_i2c_tx_byte : std_logic_vector(7 downto 0); + signal sfp_i2c_rx_byte : std_logic_vector(7 downto 0); + signal sfp_i2c_r_done : std_logic; + signal sfp_i2c_w_done : std_logic; + signal sfp_ddm_din : t_sfp_ddm_serial_id := (others => (others => '0')); + signal sfp_ddm_reg : t_sfp_ddm_serial_id := (others => (others => '0')); + signal sfp_ddm_addr : unsigned(5 downto 0); + signal sfp_ddm_sum : unsigned(7 downto 0); + +begin -- architecture rtl + + cmp_gc_i2c_slave : gc_i2c_slave + generic map ( + g_auto_addr_ack => TRUE) + port map ( + clk_i => clk_i, + rst_n_i => rst_n_i, + scl_i => scl_i, + -- clock streching not implemented by module + scl_o => open, + scl_en_o => open, + sda_i => sda_i, + -- sda_o is not necessary, sda_en has all the info that we need + sda_o => open, + sda_en_o => sda_en_o, + -- standard SFP management I2C address + i2c_addr_i => "1010000", + -- no need to ACK, we use auto address ACK + -- and only use one byte writes + ack_i => '0', + tx_byte_i => sfp_i2c_tx_byte, + rx_byte_o => sfp_i2c_rx_byte, + -- we only care about r_done (new address) + -- and w_done (load next byte from serial_id) + i2c_sta_p_o => open, + i2c_sto_p_o => open, + addr_good_p_o => open, + r_done_p_o => sfp_i2c_r_done, + w_done_p_o => sfp_i2c_w_done, + op_o => open); + + -- Populate the sfp_ddm Vendor PN using the sfp_data_i input + gen_sfp_ddm_data : for i in 0 to 15 generate + sfp_ddm_din(40+i) <= sfp_data_i(127-i*8 downto 120-i*8); + end generate gen_sfp_ddm_data; + + -- Calculate CC_BASE for the last byte of the sfp_ddm. + -- We only sum the 16 bytes, all other bytes are zero anyway. + sfp_ddm_sum <= + (((unsigned(sfp_data_i(127 downto 120)) + unsigned(sfp_data_i(119 downto 112))) + + (unsigned(sfp_data_i(111 downto 104)) + unsigned(sfp_data_i(103 downto 96)))) + + ((unsigned(sfp_data_i(95 downto 88)) + unsigned(sfp_data_i(87 downto 80))) + + (unsigned(sfp_data_i(79 downto 72)) + unsigned(sfp_data_i(71 downto 64))))) + + (((unsigned(sfp_data_i(63 downto 56)) + unsigned(sfp_data_i(55 downto 48))) + + (unsigned(sfp_data_i(47 downto 40)) + unsigned(sfp_data_i(39 downto 32)))) + + ((unsigned(sfp_data_i(31 downto 24)) + unsigned(sfp_data_i(23 downto 16))) + + (unsigned(sfp_data_i(15 downto 8)) + unsigned(sfp_data_i(7 downto 0))))); + + sfp_ddm_din(63) <= std_logic_vector(sfp_ddm_sum); + + -- always offer to send the next byte pointed to by the address counter + sfp_i2c_tx_byte <= sfp_ddm_reg(to_integer(sfp_ddm_addr)); + + -- Drive the SFP DDM based on the r_done/w_done pulses + p_sfp_ddm_addr_counter : process (clk_i) is + begin + if rising_edge(clk_i) then + if rst_n_i = '0' then + sfp_ddm_addr <= (others => '0'); + sfp_ddm_reg <= (others => (others => '0')); + else + -- check valid flag to load DDM register + if sfp_det_valid_i = '1' then + sfp_ddm_reg <= sfp_ddm_din; + else + sfp_ddm_reg <= (others => (others => '0')); + end if; + + if sfp_i2c_r_done = '1' then + -- update address pointer with new value + sfp_ddm_addr <= unsigned(sfp_i2c_rx_byte(5 downto 0)); + elsif sfp_i2c_w_done = '1' then + -- increase address pointer + sfp_ddm_addr <= sfp_ddm_addr + 1; + end if; + end if; + end if; + end process p_sfp_ddm_addr_counter; + + +end architecture rtl; diff --git a/modules/common/gencores_pkg.vhd b/modules/common/gencores_pkg.vhd index ce52e7d9d68273227d0d3734d5dcd7684a3d7a73..e5b0027c88c6f033ef974489650c73d77dbfe4db 100644 --- a/modules/common/gencores_pkg.vhd +++ b/modules/common/gencores_pkg.vhd @@ -608,6 +608,21 @@ package gencores_pkg is id_ok_o : out std_logic); end component gc_ds182x_readout; + ------------------------------------------------------------------------------ + -- SFP I2C Adapter + ------------------------------------------------------------------------------ + + component gc_sfp_i2c_adapter is + port ( + clk_i : in std_logic; + rst_n_i : in std_logic; + scl_i : in std_logic; + sda_i : in std_logic; + sda_en_o : out std_logic; + sfp_det_valid_i : in std_logic; + sfp_data_i : in std_logic_vector (127 downto 0)); + end component gc_sfp_i2c_adapter; + --============================================================================ -- Procedures and functions --============================================================================ diff --git a/modules/genrams/common/inferred_async_fifo.vhd b/modules/genrams/common/inferred_async_fifo.vhd index 8b1ba6310afc294fb6dd21a92485ee5264f256da..949661680bab602c431b9c18c340ed5919f9a95a 100644 --- a/modules/genrams/common/inferred_async_fifo.vhd +++ b/modules/genrams/common/inferred_async_fifo.vhd @@ -37,20 +37,20 @@ entity inferred_async_fifo is generic ( g_data_width : natural; g_size : natural; - g_show_ahead : boolean := false; + g_show_ahead : boolean := FALSE; -- Read-side flag selection - g_with_rd_empty : boolean := true; -- with empty flag - g_with_rd_full : boolean := false; -- with full flag - g_with_rd_almost_empty : boolean := false; - g_with_rd_almost_full : boolean := false; - g_with_rd_count : boolean := false; -- with words counter - - g_with_wr_empty : boolean := false; - g_with_wr_full : boolean := true; - g_with_wr_almost_empty : boolean := false; - g_with_wr_almost_full : boolean := false; - g_with_wr_count : boolean := false; + g_with_rd_empty : boolean := TRUE; -- with empty flag + g_with_rd_full : boolean := FALSE; -- with full flag + g_with_rd_almost_empty : boolean := FALSE; + g_with_rd_almost_full : boolean := FALSE; + g_with_rd_count : boolean := FALSE; -- with words counter + + g_with_wr_empty : boolean := FALSE; + g_with_wr_full : boolean := TRUE; + g_with_wr_almost_empty : boolean := FALSE; + g_with_wr_almost_full : boolean := FALSE; + g_with_wr_count : boolean := FALSE; g_almost_empty_threshold : integer; -- threshold for almost empty flag g_almost_full_threshold : integer -- threshold for almost full flag @@ -67,7 +67,7 @@ entity inferred_async_fifo is wr_empty_o : out std_logic; wr_full_o : out std_logic; - wr_almost_empty_o : out std_logic; -- TODO: assign + wr_almost_empty_o : out std_logic; wr_almost_full_o : out std_logic; wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0); @@ -79,7 +79,7 @@ entity inferred_async_fifo is rd_empty_o : out std_logic; rd_full_o : out std_logic; rd_almost_empty_o : out std_logic; - rd_almost_full_o : out std_logic; -- TODO: assign + rd_almost_full_o : out std_logic; rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0) ); @@ -88,50 +88,49 @@ end inferred_async_fifo; architecture syn of inferred_async_fifo is - function f_bin2gray(bin : std_logic_vector) return std_logic_vector is - begin - return bin(bin'left) & (bin(bin'left-1 downto 0) xor bin(bin'left downto 1)); - end f_bin2gray; - - function f_gray2bin(gray : std_logic_vector) return std_logic_vector is - variable bin : std_logic_vector(gray'left downto 0); - begin - -- gray to binary - for i in 0 to gray'left loop - bin(i) := '0'; - for j in i to gray'left loop - bin(i) := bin(i) xor gray(j); - end loop; -- j - end loop; -- i - return bin; - end f_gray2bin; - + -- We use one more bit to be able to differentiate between an empty FIFO + -- (where rcb = wcb) and a full FIFO (where rcb = wcb except from the most + -- significant extra bit). + -- This extra bit is not used of course for actual addressing of the memory. constant c_counter_bits : integer := f_log2_size(g_size) + 1; + subtype t_counter is std_logic_vector(c_counter_bits-1 downto 0); + -- bin: binary counter + -- bin_next: bin + 1 + -- bin_x: cross-clock domain version of bin + -- gray: gray code of bin + -- gray_next: gray code of bin_next + -- gray_x: gray code of bin_x + -- + -- We use gray codes for safe cross-clock domain crossing of counters. Thus, + -- a binary counter is converted to gray before crossing, and then it is + -- converted back to binary after crossing. type t_counter_block is record - bin, bin_next, gray, gray_next : t_counter; - bin_x, gray_x, gray_xm : t_counter; + bin, bin_next : t_counter; + gray, gray_next : t_counter; + bin_x, gray_x : t_counter; end record; - type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0); - signal mem : t_mem_type; + type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0); + signal mem : t_mem_type := (others => (others => '0')); + + signal rcb, wcb : t_counter_block; - signal rcb, wcb : t_counter_block; + signal rd_ptr_muxed : t_counter; - signal full_int, empty_int : std_logic; signal almost_full_int, almost_empty_int : std_logic; signal going_full : std_logic; signal wr_count, rd_count : t_counter; - signal rd_int, we_int : std_logic; + signal rd_int, we_int : std_logic; - signal wr_empty_xm, wr_empty_x : std_logic; - signal rd_full_xm, rd_full_x : std_logic; + signal wr_empty_x : std_logic; + signal rd_full_x : std_logic; - signal almost_full_x, almost_full_xm : std_logic; - signal almost_empty_x, almost_empty_xm : std_logic; + signal almost_full_x : std_logic; + signal almost_empty_x : std_logic; signal q_int : std_logic_vector(g_data_width-1 downto 0) := (others => '0'); @@ -140,28 +139,37 @@ begin -- syn rd_int <= rd_i and not empty_int; we_int <= we_i and not full_int; + p_rd_ptr_mux : process(rcb, rd_int) + begin + if(rd_int = '1' and g_show_ahead) then + rd_ptr_muxed <= rcb.bin_next; + elsif((rd_int = '1' and not g_show_ahead) or (g_show_ahead)) then + rd_ptr_muxed <= rcb.bin; + end if; + end process p_rd_ptr_mux; + p_mem_write : process(clk_wr_i) begin if rising_edge(clk_wr_i) then if(we_int = '1') then - mem(to_integer(unsigned(wcb.bin(wcb.bin'left-1 downto 0)))) <= d_i; + mem(to_integer(unsigned(wcb.bin(wcb.bin'LEFT-1 downto 0)))) <= d_i; end if; end if; - end process; + end process p_mem_write; p_mem_read : process(clk_rd_i) begin if rising_edge(clk_rd_i) then - if(rd_int = '1') then - q_int <= mem(to_integer(unsigned(rcb.bin(rcb.bin'left-1 downto 0)))); + if(rd_int = '1' or g_show_ahead) then + q_int <= mem(to_integer(unsigned(rd_ptr_muxed(rd_ptr_muxed'LEFT-1 downto 0)))); end if; end if; - end process; + end process p_mem_read; q_o <= q_int; wcb.bin_next <= std_logic_vector(unsigned(wcb.bin) + 1); - wcb.gray_next <= f_bin2gray(wcb.bin_next); + wcb.gray_next <= f_gray_encode(wcb.bin_next); p_write_ptr : process(clk_wr_i, rst_n_i) begin @@ -174,10 +182,10 @@ begin -- syn wcb.gray <= wcb.gray_next; end if; end if; - end process; + end process p_write_ptr; rcb.bin_next <= std_logic_vector(unsigned(rcb.bin) + 1); - rcb.gray_next <= f_bin2gray(rcb.bin_next); + rcb.gray_next <= f_gray_encode(rcb.bin_next); p_read_ptr : process(clk_rd_i, rst_n_i) begin @@ -190,28 +198,28 @@ begin -- syn rcb.gray <= rcb.gray_next; end if; end if; - end process; + end process p_read_ptr; - U_Sync1: gc_sync_register + U_Sync1 : gc_sync_register generic map ( g_width => c_counter_bits) port map ( - clk_i => clk_wr_i, - rst_n_a_i => rst_n_i, - d_i => rcb.gray, - q_o => rcb.gray_x); + clk_i => clk_wr_i, + rst_n_a_i => rst_n_i, + d_i => rcb.gray, + q_o => rcb.gray_x); - U_Sync2: gc_sync_register + U_Sync2 : gc_sync_register generic map ( g_width => c_counter_bits) port map ( - clk_i => clk_rd_i, - rst_n_a_i => rst_n_i, - d_i => wcb.gray, - q_o => wcb.gray_x); + clk_i => clk_rd_i, + rst_n_a_i => rst_n_i, + d_i => wcb.gray, + q_o => wcb.gray_x); - wcb.bin_x <= f_gray2bin(wcb.gray_x); - rcb.bin_x <= f_gray2bin(rcb.gray_x); + wcb.bin_x <= f_gray_decode(wcb.gray_x, 1); + rcb.bin_x <= f_gray_decode(rcb.gray_x, 1); p_gen_empty : process(clk_rd_i, rst_n_i) begin @@ -224,9 +232,9 @@ begin -- syn empty_int <= '0'; end if; end if; - end process; + end process p_gen_empty; - U_Sync_Empty: gc_sync_ffs + U_Sync_Empty : gc_sync_ffs generic map ( g_sync_edge => "positive") port map ( @@ -235,7 +243,7 @@ begin -- syn data_i => empty_int, synced_o => wr_empty_x); - U_Sync_Full: gc_sync_ffs + U_Sync_Full : gc_sync_ffs generic map ( g_sync_edge => "positive") port map ( @@ -243,25 +251,23 @@ begin -- syn rst_n_i => rst_n_i, data_i => full_int, synced_o => rd_full_x); - - rd_empty_o <= empty_int; wr_empty_o <= wr_empty_x; p_gen_going_full : process(we_int, wcb, rcb) begin - if ((wcb.bin (wcb.bin'left-1 downto 0) = rcb.bin_x(rcb.bin_x'left-1 downto 0)) - and (wcb.bin(wcb.bin'left) /= rcb.bin_x(rcb.bin_x'left))) then + if ((wcb.bin (wcb.bin'LEFT-1 downto 0) = rcb.bin_x(rcb.bin_x'LEFT-1 downto 0)) + and (wcb.bin(wcb.bin'LEFT) /= rcb.bin_x(rcb.bin_x'LEFT))) then going_full <= '1'; elsif (we_int = '1' - and (wcb.bin_next(wcb.bin'left-1 downto 0) = rcb.bin_x(rcb.bin_x'left-1 downto 0)) - and (wcb.bin_next(wcb.bin'left) /= rcb.bin_x(rcb.bin_x'left))) then + and (wcb.bin_next(wcb.bin'LEFT-1 downto 0) = rcb.bin_x(rcb.bin_x'LEFT-1 downto 0)) + and (wcb.bin_next(wcb.bin'LEFT) /= rcb.bin_x(rcb.bin_x'LEFT))) then going_full <= '1'; else going_full <= '0'; end if; - end process; + end process p_gen_going_full; p_register_full : process(clk_wr_i, rst_n_i) begin @@ -270,7 +276,7 @@ begin -- syn elsif rising_edge (clk_wr_i) then full_int <= going_full; end if; - end process; + end process p_register_full; wr_full_o <= full_int; rd_full_o <= rd_full_x; @@ -287,9 +293,9 @@ begin -- syn almost_full_int <= '0'; end if; end if; - end process; + end process p_reg_almost_full; - U_Sync_AlmostFull: gc_sync_ffs + U_Sync_AlmostFull : gc_sync_ffs generic map ( g_sync_edge => "positive") port map ( @@ -298,24 +304,24 @@ begin -- syn data_i => almost_full_int, synced_o => almost_full_x); - wr_almost_full_o <= almost_full_int; - rd_almost_full_o <= almost_full_x; + wr_almost_full_o <= almost_full_int; + rd_almost_full_o <= almost_full_x; p_reg_almost_empty : process(clk_rd_i, rst_n_i) begin if rst_n_i = '0' then almost_empty_int <= '1'; elsif rising_edge(clk_rd_i) then - rd_count <= std_logic_vector(unsigned(wcb.bin_x) - unsigned(rcb.bin)); + rd_count <= std_logic_vector(unsigned(wcb.bin_x) - unsigned(rcb.bin)); if (unsigned(rd_count) <= g_almost_empty_threshold) then almost_empty_int <= '1'; else almost_empty_int <= '0'; end if; end if; - end process; + end process p_reg_almost_empty; - U_Sync_AlmostEmpty: gc_sync_ffs + U_Sync_AlmostEmpty : gc_sync_ffs generic map ( g_sync_edge => "positive") port map ( diff --git a/modules/genrams/common/inferred_async_fifo_dual_rst.vhd b/modules/genrams/common/inferred_async_fifo_dual_rst.vhd index 0cb8657f90fa889f73a06b3a0d3e0385157ec02d..be6b94d4deac3f5e6618c0976b916925c973e759 100644 --- a/modules/genrams/common/inferred_async_fifo_dual_rst.vhd +++ b/modules/genrams/common/inferred_async_fifo_dual_rst.vhd @@ -77,21 +77,37 @@ entity inferred_async_fifo_dual_rst is end inferred_async_fifo_dual_rst; -architecture syn of inferred_async_fifo_dual_rst is +architecture arch of inferred_async_fifo_dual_rst is + -- We use one more bit to be able to differentiate between an empty FIFO + -- (where rcb = wcb) and a full FIFO (where rcb = wcb except from the most + -- significant extra bit). + -- This extra bit is not used of course for actual addressing of the memory. constant c_counter_bits : integer := f_log2_size(g_size) + 1; subtype t_counter is std_logic_vector(c_counter_bits-1 downto 0); + -- bin: binary counter + -- bin_next: bin + 1 + -- bin_x: cross-clock domain version of bin + -- gray: gray code of bin + -- gray_next: gray code of bin_next + -- gray_x: gray code of bin_x + -- + -- We use gray codes for safe cross-clock domain crossing of counters. Thus, + -- a binary counter is converted to gray before crossing, and then it is + -- converted back to binary after crossing. type t_counter_block is record - bin, bin_next, gray, gray_next : t_counter; - bin_x, gray_x, gray_xm : t_counter; + bin, bin_next : t_counter; + gray, gray_next : t_counter; + bin_x, gray_x : t_counter; end record; type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0); - signal mem : t_mem_type; + signal mem : t_mem_type := (others => (others => '0')); signal rcb, wcb : t_counter_block; + signal rd_ptr_muxed : t_counter; signal full_int, empty_int : std_logic; signal almost_full_int, almost_empty_int : std_logic; @@ -100,19 +116,28 @@ architecture syn of inferred_async_fifo_dual_rst is signal wr_count, rd_count : t_counter; signal rd_int, we_int : std_logic; - signal wr_empty_xm, wr_empty_x : std_logic; - signal rd_full_xm, rd_full_x : std_logic; + signal wr_empty_x : std_logic; + signal rd_full_x : std_logic; - signal almost_full_x, almost_full_xm : std_logic; - signal almost_empty_x, almost_empty_xm : std_logic; + signal almost_full_x : std_logic; + signal almost_empty_x : std_logic; signal q_int : std_logic_vector(g_data_width-1 downto 0) := (others => '0'); -begin -- syn +begin -- arch rd_int <= rd_i and not empty_int; we_int <= we_i and not full_int; + p_rd_ptr_mux : process(rcb, rd_int) + begin + if(rd_int = '1' and g_show_ahead) then + rd_ptr_muxed <= rcb.bin_next; + elsif((rd_int = '1' and not g_show_ahead) or (g_show_ahead)) then + rd_ptr_muxed <= rcb.bin; + end if; + end process p_rd_ptr_mux; + p_mem_write : process(clk_wr_i) begin if rising_edge(clk_wr_i) then @@ -125,8 +150,8 @@ begin -- syn p_mem_read : process(clk_rd_i) begin if rising_edge(clk_rd_i) then - if rd_int = '1' then - q_int <= mem(to_integer(unsigned(rcb.bin(rcb.bin'LEFT-1 downto 0)))); + if(rd_int = '1' or g_show_ahead) then + q_int <= mem(to_integer(unsigned(rd_ptr_muxed(rd_ptr_muxed'LEFT-1 downto 0)))); end if; end if; end process p_mem_read; @@ -307,4 +332,4 @@ begin -- syn wr_count_o <= std_logic_vector(wr_count(f_log2_size(g_size)-1 downto 0)); rd_count_o <= std_logic_vector(rd_count(f_log2_size(g_size)-1 downto 0)); -end syn; +end arch; diff --git a/modules/genrams/common/inferred_sync_fifo.vhd b/modules/genrams/common/inferred_sync_fifo.vhd index ed7de11bbf0a6da78770e09f0468db3d62d808ce..45c59f704f2c68f09db9653c6d1cf26cb4d38443 100644 --- a/modules/genrams/common/inferred_sync_fifo.vhd +++ b/modules/genrams/common/inferred_sync_fifo.vhd @@ -81,12 +81,12 @@ architecture syn of inferred_sync_fifo is signal guard_bit : std_logic; signal q_comb : std_logic_vector(g_data_width-1 downto 0); - + begin -- syn we_int <= we_i and not full; rd_int <= rd_i and not empty; - + U_FIFO_Ram : generic_dpram generic map ( g_data_width => g_data_width, @@ -104,7 +104,7 @@ begin -- syn ab_i => std_logic_vector(rd_ptr_muxed(c_pointer_width-1 downto 0)), qb_o => q_comb); - process(rd_ptr, rd_i, rd_int) + p_rd_ptr_mux: process(rd_int, rd_ptr) begin if(rd_int = '1' and g_show_ahead) then rd_ptr_muxed <= rd_ptr + 1; @@ -113,7 +113,7 @@ begin -- syn else rd_ptr_muxed <= rd_ptr - 1; end if; - end process; + end process p_rd_ptr_mux; q_o <= q_comb; @@ -173,7 +173,7 @@ begin -- syn p_reg_flags : process(clk_i) begin if rising_edge(clk_i) then - + if(rst_n_i = '0') then full <= '0'; empty <= '1'; @@ -190,7 +190,7 @@ begin -- syn full <= '0'; end if; end if; - + end if; end process; end generate gen_registered_flags; diff --git a/modules/wishbone/wb_crossbar/xwb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_crossbar.vhd index 8ba53a2fdf4a859cb34161d9b55cc93376ee0ce8..cf77bb0a0846e1cbb1ec6c316b49b976719b7f97 100644 --- a/modules/wishbone/wb_crossbar/xwb_crossbar.vhd +++ b/modules/wishbone/wb_crossbar/xwb_crossbar.vhd @@ -55,7 +55,9 @@ entity xwb_crossbar is g_registered : boolean := false; -- Address of the slaves connected g_address : t_wishbone_address_array; - g_mask : t_wishbone_address_array); + g_mask : t_wishbone_address_array; + -- Set to false to skip "Mapping Slave" notes during simulation + g_verbose : boolean := true); port( clk_sys_i : in std_logic; rst_n_i : in std_logic; @@ -111,10 +113,12 @@ architecture rtl of xwb_crossbar is severity Failure; -- Working case - report "Mapping slave #" & - Integer'image(i) & "[" & f_bits2string(c_address(i)) & "/" & - f_bits2string(c_mask(i)) & "]" - severity Note; + if g_verbose then + report "Mapping slave #" & + Integer'image(i) & "[" & f_bits2string(c_address(i)) & "/" & + f_bits2string(c_mask(i)) & "]" + severity Note; + end if; end loop; return true; end f_ranges_ok; diff --git a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd index 9c3b26bf4a04032e7bf22e1f153493abd5858ac8..3c5f8196e91b2c18a6d2a724dbb52be6adc85e58 100644 --- a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd +++ b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd @@ -31,6 +31,7 @@ use work.wishbone_pkg.all; entity xwb_sdb_crossbar is generic( + g_verbose : boolean := true; g_num_masters : natural := 1; g_num_slaves : natural := 1; g_registered : boolean := false; @@ -232,7 +233,8 @@ begin g_num_slaves => g_num_slaves + 1, g_registered => g_registered, g_address => c_address, - g_mask => c_mask) + g_mask => c_mask, + g_verbose => g_verbose) port map( clk_sys_i => clk_sys_i, rst_n_i => rst_n_i, @@ -248,7 +250,8 @@ begin g_num_slaves => g_num_masters, g_registered => g_registered, g_address => c_addresses.msi_address, - g_mask => c_addresses.msi_mask) + g_mask => c_addresses.msi_mask, + g_verbose => g_verbose) port map( clk_sys_i => clk_sys_i, rst_n_i => rst_n_i, diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd index 573eceb12f2ccc3daa156964aedd84007e3de85f..f7a43281dc5196b87732e82982ae6a9891767582 100644 --- a/modules/wishbone/wishbone_pkg.vhd +++ b/modules/wishbone/wishbone_pkg.vhd @@ -390,7 +390,8 @@ package wishbone_pkg is g_num_slaves : integer; g_registered : boolean; g_address : t_wishbone_address_array; - g_mask : t_wishbone_address_array); + g_mask : t_wishbone_address_array; + g_verbose : boolean := true); port ( clk_sys_i : in std_logic; rst_n_i : in std_logic; @@ -419,6 +420,7 @@ package wishbone_pkg is component xwb_sdb_crossbar generic ( + g_verbose : boolean := true; g_num_masters : integer; g_num_slaves : integer; g_registered : boolean := false;