library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.ngFEC_pack.all; --use work.user_package.all; entity ipb_user_control_regs is generic(addr_width : natural := 7); port ( clk : in std_logic; reset : in std_logic; ipb_mosi_i : in ipb_wbus; ipb_miso_o : out ipb_rbus; ------------------ regs_o : out array_128x32bit ); end ipb_user_control_regs; architecture rtl of ipb_user_control_regs is component DSP_MUX Port ( DinA : in STD_LOGIC_VECTOR (47 downto 0); DinB : in STD_LOGIC_VECTOR (47 downto 0); PCIN : in STD_LOGIC_VECTOR (47 downto 0); S : in STD_LOGIC_VECTOR (1 downto 0); PCOUT : out STD_LOGIC_VECTOR (47 downto 0); Dout : out STD_LOGIC_VECTOR (47 downto 0)); end component; component DSP_MUX_b Port ( DinA : in STD_LOGIC_VECTOR (47 downto 0); DinB : in STD_LOGIC_VECTOR (47 downto 0); S : in STD_LOGIC_VECTOR (1 downto 0); PCOUT : out STD_LOGIC_VECTOR (47 downto 0); Dout : out STD_LOGIC_VECTOR (47 downto 0)); end component; type array8X48 is array(0 to 7) of std_logic_vector(47 downto 0); type array64X48 is array(0 to 63) of std_logic_vector(47 downto 0); type array128X48 is array(0 to 127) of std_logic_vector(47 downto 0); signal DIN : array128x48 := (others => (others => '0')); signal PCIN : array64x48 := (others => (others => '0')); signal PCOUT : array64x48; signal Dout : array64x48; signal PCIN2 : array8x48 := (others => (others => '0')); signal PCOUT2 : array8x48; signal Dout2 : array8x48; signal S1 : std_logic_vector(7 downto 0); signal S2 : std_logic_vector(15 downto 0); signal regs: array_128x32bit := (others => (others => '0')); signal sel: integer range 0 to 127; attribute keep: boolean; attribute keep of sel: signal is true; begin --=============================-- -- io mapping --=============================-- regs_o <= regs; --=============================-- sel <= to_integer(unsigned(ipb_mosi_i.ipb_addr(addr_width downto 0))) when addr_width>0 else 0; --=============================-- --=============================-- process(reset, clk) --=============================-- begin if reset='1' then regs <= (others=> (others=>'0')); regs(2) <= x"00000042"; --the I2C prescale elsif rising_edge(clk) then if ipb_mosi_i.ipb_strobe='1' and ipb_mosi_i.ipb_write='1' then regs(sel) <= ipb_mosi_i.ipb_wdata; end if; end if; end process; ipb_miso_o.ipb_err <= '0'; ipb_miso_o.ipb_ack <= ipb_mosi_i.ipb_strobe; ipb_miso_o.ipb_rdata <= Dout2(7)(31 downto 0); process(ipb_mosi_i,S1,S2) begin case ipb_mosi_i.ipb_addr(2 downto 0) is when "000" => S1 <= x"02"; when "001" => S1 <= x"03"; when "010" => S1 <= x"08"; when "011" => S1 <= x"0c"; when "100" => S1 <= x"20"; when "101" => S1 <= x"30"; when "110" => S1 <= x"80"; when others => S1 <= x"c0"; end case; case ipb_mosi_i.ipb_addr(6 downto 3) is when x"0" => S2 <= x"0002"; when x"1" => S2 <= x"0003"; when x"2" => S2 <= x"0008"; when x"3" => S2 <= x"000c"; when x"4" => S2 <= x"0020"; when x"5" => S2 <= x"0030"; when x"6" => S2 <= x"0080"; when x"7" => S2 <= x"00c0"; when x"8" => S2 <= x"0200"; when x"9" => S2 <= x"0300"; when x"a" => S2 <= x"0800"; when x"b" => S2 <= x"0c00"; when x"c" => S2 <= x"2000"; when x"d" => S2 <= x"3000"; when x"e" => S2 <= x"8000"; when others => S2 <= x"c000"; end case; end process; g_Din : for i in 0 to 127 generate Din(i)(31 downto 0) <= regs(i); end generate g_din; g_MUX_j : for j in 0 to 15 generate i_DSP_MUX_b : DSP_MUX_b port map( DinA => Din(j*8), DinB => Din(j*8+1), S => S1(1 downto 0), PCOUT => PCOUT(j*4), Dout => Dout(j*4)); g_MUX_i : for i in 1 to 3 generate i_DSP_MUX : DSP_MUX port map( DinA => Din(j*8+i*2), DinB => Din(j*8+i*2+1), PCIN => PCIN(j*4+i), S => S1(i*2+1 downto i*2), PCOUT => PCOUT(j*4+i), Dout => Dout(j*4+i)); end generate g_MUX_i; g_PCIN : for i in 1 to 3 generate PCIN(j*4+i) <= PCOUT(j*4+i-1); end generate g_PCIN; end generate g_MUX_j; i_DSP_MUX_b : DSP_MUX_b port map( DinA => Dout(3), DinB => Dout(7), S => S2(1 downto 0), PCOUT => PCOUT2(0), Dout => Dout2(0)); g_MUX_i : for i in 1 to 7 generate i_DSP_MUX : DSP_MUX port map( DinA => Dout(i*8+3), DinB => Dout(i*8+7), PCIN => PCIN2(i), S => S2(i*2+1 downto i*2), PCOUT => PCOUT2(i), Dout => Dout2(i)); end generate g_MUX_i; g_PCIN : for i in 1 to 7 generate PCIN2(i) <= PCOUT2(i-1); end generate g_PCIN; end rtl;