diff --git a/modules/common/Manifest.py b/modules/common/Manifest.py index 2e185e105bf76dc575076da8c2378a55ce285557..44c4c995b71ad5944ea6a02aea4a70e6da007473 100644 --- a/modules/common/Manifest.py +++ b/modules/common/Manifest.py @@ -10,4 +10,7 @@ files = [ "gencores_pkg.vhd", "gc_arbitrated_mux.vhd", "gc_pulse_synchronizer.vhd", "gc_frequency_meter.vhd", - "gc_wfifo.vhd"]; + "gc_dual_clock_ram.vhd", + "gc_wfifo.vhd", + "gc_rr_arbiter.vhd", + "gc_prio_encoder.vhd"]; diff --git a/modules/common/gc_prio_encoder.vhd b/modules/common/gc_prio_encoder.vhd new file mode 100644 index 0000000000000000000000000000000000000000..bc517e8f6fbbe7b0162e41d5769e98e42fbbb23b --- /dev/null +++ b/modules/common/gc_prio_encoder.vhd @@ -0,0 +1,61 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity gc_prio_encoder is + + generic ( + g_width : integer + ); + port ( + d_i : in std_logic_vector(g_width-1 downto 0); + therm_o : out std_logic_vector(g_width-1 downto 0) + ); + +end gc_prio_encoder; + + +architecture rtl of gc_prio_encoder is + + function f_count_stages(width : integer) return integer is + begin + if(width <= 2) then + return 2; + elsif(width <= 4) then + return 3; + elsif(width <= 8) then + return 4; + elsif(width <= 16) then + return 5; + elsif(width <= 32) then + return 6; + elsif(width <= 64) then + return 7; + elsif(width <= 128) then + return 8; + else + return 0; + end if; + end f_count_stages; + + constant c_n_stages : integer := f_count_stages(g_width); + + type t_stage_array is array(0 to c_n_stages) of std_logic_vector(g_width-1 downto 0); + signal stages : t_stage_array; +begin -- rtl + + stages(0) <= d_i; + + gen1 : for i in 1 to c_n_stages generate + gen2 : for j in 0 to g_width-1 generate + gen3 : if(j mod (2 ** i) >= (2 ** (i-1))) generate + stages(i)(j) <= stages(i-1)(j) or stages(i-1) (j - (j mod (2**i)) + (2**(i-1)) - 1); + end generate gen3; + gen4 : if not (j mod (2 ** i) >= (2 ** (i-1))) generate + stages(i)(j) <= stages(i-1)(j); + end generate gen4; + end generate gen2; + end generate gen1; + + therm_o <= stages(c_n_stages); +end rtl; diff --git a/modules/common/gc_rr_arbiter.vhd b/modules/common/gc_rr_arbiter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1ead771523981a8ce45bb3eb0f1ededbeb900eff --- /dev/null +++ b/modules/common/gc_rr_arbiter.vhd @@ -0,0 +1,83 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity gc_rr_arbiter is + + generic ( + g_size : integer := 19); + + port ( + clk_i : in std_logic; + rst_n_i : in std_logic; + req_i : in std_logic_vector(g_size-1 downto 0); + grant_o : out std_logic_vector(g_size-1 downto 0); + grant_comb_o: out std_logic_vector(g_size-1 downto 0) + ); + + attribute opt_mode: string; + attribute opt_mode of gc_rr_arbiter: entity is "speed"; + attribute resource_sharing: string; + attribute resource_sharing of gc_rr_arbiter: entity is "no"; +end gc_rr_arbiter; + + +architecture rtl of gc_rr_arbiter is + + + + component gc_prio_encoder + generic ( + g_width : integer); + port ( + d_i : in std_logic_vector(g_width-1 downto 0); + therm_o : out std_logic_vector(g_width-1 downto 0)); + end component; + + signal req_m, th_m, th_u, mux_out, mask : std_logic_vector(g_size-1 downto 0); + +begin -- rtl + + req_m<=req_i and mask; + + U_PE1 : gc_prio_encoder + generic map ( + g_width => g_size) + port map ( + d_i => req_m, + therm_o => th_m); + + U_PE2 : gc_prio_encoder + generic map ( + g_width => g_size) + port map ( + d_i => req_i, + therm_o => th_u); + + + process(th_u, th_m) + begin + if(th_m(th_m'length - 1) = '0') then + mux_out <= th_u; + else + mux_out <= th_m; + end if; + end process; + + + process(clk_i) + begin + if rising_edge(clk_i) then + if rst_n_i = '0' then + mask <= (others => '0'); + grant_o <= (others => '0'); + else + mask <= mux_out(g_size-2 downto 0) & '0'; + grant_o <= not (mux_out(g_size-2 downto 0) & '0') and mux_out; + end if; + end if; + end process; + + grant_comb_o <= not (mux_out(g_size-2 downto 0) & '0') and mux_out; + +end rtl; diff --git a/modules/common/gencores_pkg.vhd b/modules/common/gencores_pkg.vhd index 91f65568c42dfc469e18ea3b6860cc9cb0ff6eac..6024f660b79a7ed94d46227fe61940b42f6e1707 100644 --- a/modules/common/gencores_pkg.vhd +++ b/modules/common/gencores_pkg.vhd @@ -6,7 +6,7 @@ -- Author : Tomasz Wlostowski -- Company : CERN -- Created : 2009-09-01 --- Last update: 2012-03-12 +-- Last update: 2012-07-05 -- Platform : FPGA-generic -- Standard : VHDL '93 ------------------------------------------------------------------------------- @@ -188,7 +188,7 @@ package gencores_pkg is q_valid_o : out std_logic; q_input_id_o : out std_logic_vector(f_log2_size(g_num_inputs)-1 downto 0)); end component; - + -- A 'Wes' FIFO. Generic FIFO using inferred memory. -- Supports clock domain crossing -- Should be safe from fast->slow or reversed @@ -233,6 +233,17 @@ package gencores_pkg is rstn_o : out std_logic_vector(g_clocks-1 downto 0)); end component; + component gc_rr_arbiter + generic ( + g_size : integer); + port ( + clk_i : in std_logic; + rst_n_i : in std_logic; + req_i : in std_logic_vector(g_size-1 downto 0); + grant_o : out std_logic_vector(g_size-1 downto 0); + grant_comb_o : out std_logic_vector(g_size-1 downto 0)); + end component; + procedure f_rr_arbitrate ( signal req : in std_logic_vector; signal pre_grant : in std_logic_vector;