-- -- Hail Simulation Components -- -- -- Link Connect module -- -- Behavioral model of a single link connection -- DST_RDY always '1' -- Routes TX signals to RX library ieee; use ieee.std_logic_1164.all; library work; use work.common_interface.all; use work.hail_simulation.all; entity link_connect is port ( linkA_out : in link_out_type; linkA_in : out link_in_type; linkB_out : in link_out_type; linkB_in : out link_in_type); end link_connect; architecture behave of link_connect is begin linkA_in.tx_dst_rdy <= '1'; linkB_in.tx_dst_rdy <= '1'; linkA_in.rx_data <= linkB_out.tx_data; linkA_in.rx_src_rdy <= linkB_out.tx_src_rdy; linkA_in.rx_sof <= linkB_out.tx_sof; linkA_in.rx_eof <= linkB_out.tx_eof; linkB_in.rx_data <= linkA_out.tx_data; linkB_in.rx_src_rdy <= linkA_out.tx_src_rdy; linkB_in.rx_sof <= linkA_out.tx_sof; linkB_in.rx_eof <= linkA_out.tx_eof; end behave; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use ieee.std_logic_misc.all; library work; use work.common_interface.all; use work.hail_simulation.all; entity hail_simulator is generic ( board : board_type := adm_xp; number_of_memories : integer := 6); port ( clk : in std_logic; rst : in std_logic; system_out : in std_logic_vector(system_width-1 downto 0); system_in : out std_logic_vector(system_width-1 downto 0); links_in : in links_in_type; links_out : out links_out_type; host_in : in host_in_type; host_out : out host_out_type); end hail_simulator; architecture behave of hail_simulator is signal ctrl_bus_ivec : std_logic_vector(ctrl_bus_width-1 downto 0) := (others => '0'); signal status_bus_ivec : std_logic_vector(status_bus_width-1 downto 0) := (others => '0'); signal irq_bus_ivec : std_logic_vector(interrupt_bus_width-1 downto 0) := (others => '0'); signal bram_bus_ivec : std_logic_vector(bram_bus_width-1 downto 0) := (others => '0'); signal locallinks_ivec : std_logic_vector(4*locallink_type_width-1 downto 0) := (others => '0'); signal extrams_ivec : std_logic_vector(6*extmem_type_width-1 downto 0) := (others => '0'); signal ctrl_bus_ovec : std_logic_vector(ctrl_bus_width-1 downto 0) := (others => '0'); signal status_bus_ovec : std_logic_vector(status_bus_width-1 downto 0) := (others => '0'); signal irq_bus_ovec : std_logic_vector(interrupt_bus_width-1 downto 0) := (others => '0'); signal bram_bus_ovec : std_logic_vector(bram_bus_width-1 downto 0) := (others => '0'); signal locallinks_ovec : std_logic_vector(4*locallink_type_width-1 downto 0) := (others => '0'); signal extrams_ovec : std_logic_vector(6*extmem_type_width-1 downto 0) := (others => '0'); signal lclk_dummy : std_logic := '0'; signal irq_bus : interrupt_bus_type := (ier => (others => '0'), isr => (others => '0')); type extmem_array_type is array (0 to 5) of extmem_type; signal eram_in,eram_out : extmem_array_type; type locallink_array is array (0 to 3) of locallink_type; signal locallinks_o,locallinks_i : locallink_array; constant bank_size : integer := 2**16; type memory_bank_type is array (0 to bank_size-1) of integer; type memory_bank_array is array (0 to number_of_memories-1) of memory_bank_type; type q_type is array (0 to 5) of std_logic_vector(63 downto 0); signal q : q_type; signal ram_gnt : std_logic_vector(5 downto 0) := "000000"; signal ram_busy : std_logic_vector(5 downto 0) := "000000"; type qpipe_type is array (0 to 15) of std_logic_vector(63 downto 0); begin -- Split output system signals and convert data types split0 : split_system_signal( system => system_out, lclk => lclk_dummy, ctrl_bus => ctrl_bus_ovec, status_bus => status_bus_ovec, irq_bus => irq_bus_ovec, bram_bus => bram_bus_ovec, locallinks => locallinks_ovec, extrams => extrams_ovec); -- Merge signals into system inputs merge0 : build_system_signal ( system => system_in, lclk => host_in.clk, ctrl_bus => ctrl_bus_ivec, status_bus => status_bus_ivec, irq_bus => irq_bus_ivec, bram_bus => bram_bus_ivec, locallinks => locallinks_ivec, extrams => extrams_ivec); -- Connect Local Bus signals directly to host procedures host_out.status_bus <= slv_to_status_bus(status_bus_ovec); host_out.interrupt_bus <= slv_to_irq_bus(irq_bus_ovec); host_out.bram_bus <= slv_to_bram_bus(bram_bus_ovec); ctrl_bus_ivec <= ctrl_bus_to_slv(host_in.ctrl_bus); status_bus_ivec <= status_bus_to_slv(host_in.status_bus); irq_bus_ivec <= irq_bus_to_slv(irq_bus); bram_bus_ivec <= bram_bus_to_slv(host_in.bram_bus); -- Update IER only on IER write strobe process (host_in.interrupt_bus.ier_wstb) begin -- process if host_in.interrupt_bus.ier_wstb'event and host_in.interrupt_bus.ier_wstb = '1' then irq_bus.ier <= host_in.interrupt_bus.ier; end if; end process; irq_bus.isr <= host_in.interrupt_bus.isr; -- Connect Local Links to local link ports split_ll_out: for i in 0 to 3 generate locallinks_o(i) <= slv_to_locallink_type(locallinks_ovec((i+1)*locallink_type_width-1 downto i*locallink_type_width)); links_out(i).tx_data <= locallinks_o(i).tx_data; links_out(i).tx_src_rdy <= locallinks_o(i).tx_src_rdy; links_out(i).tx_sof <= locallinks_o(i).tx_sof; links_out(i).tx_eof <= locallinks_o(i).tx_eof; locallinks_i(i).tx_dst_rdy <= links_in(i).tx_dst_rdy; locallinks_i(i).rx_data <= links_in(i).rx_data; locallinks_i(i).rx_src_rdy <= links_in(i).rx_src_rdy; locallinks_i(i).rx_sof <= links_in(i).rx_sof; locallinks_i(i).rx_eof <= links_in(i).rx_eof; end generate split_ll_out; locallinks_ivec <= locallink_type_to_slv(locallinks_i(3)) & locallink_type_to_slv(locallinks_i(2))& locallink_type_to_slv(locallinks_i(1)) & locallink_type_to_slv(locallinks_i(0)); -- Model External RAM banks internally connect_ram: for i in 0 to number_of_memories-1 generate eram_out(i) <= slv_to_extmem_type(extrams_ovec((i+1)*extmem_type_width-1 downto i*extmem_type_width)); extrams_ivec((i+1)*extmem_type_width-1 downto i*extmem_type_width) <= extmem_type_to_slv(eram_in(i)); -- Behavioural module of multi-clock access to RAM model_ram: process (host_in.clk,clk,rst) variable mem_msw,mem_lsw : memory_bank_type; variable qpipe : qpipe_type; variable qvpipe : std_logic_vector(15 downto 0); begin -- process model_ram if rst = '1' then for j in 0 to bank_size-1 loop mem_msw(j) := 0; mem_lsw(j) := 0; end loop; -- i ram_gnt(i) <= '0'; ram_busy(i) <= '0'; for j in 0 to 15 loop qpipe(j) := (others => '0'); qvpipe(j) := '0'; end loop; -- j eram_in(i).gnt <= '0'; eram_in(i).q <= (others => '0'); eram_in(i).qv <= '0'; eram_in(i).full <= '0'; elsif rising_edge(clk) then if ram_gnt(i) = '1' and ram_busy(i) = '0' then if eram_out(i).w = '1' then mem_msw(CONV_INTEGER(eram_out(i).a)) := CONV_INTEGER(eram_out(i).d(63 downto 32)); mem_lsw(CONV_INTEGER(eram_out(i).a)) := CONV_INTEGER(eram_out(i).d(31 downto 0)); elsif eram_out(i).r = '1' then qpipe(0) := CONV_STD_LOGIC_VECTOR(mem_msw(CONV_INTEGER(eram_out(i).a)),32) & CONV_STD_LOGIC_VECTOR(mem_lsw(CONV_INTEGER(eram_out(i).a)),32); end if; qvpipe(0) := eram_out(i).r; else qvpipe(0) := '0'; end if; eram_in(i).gnt <= ram_gnt(i); eram_in(i).full <= ram_busy(i); for j in 15 downto 1 loop qpipe(j) := qpipe(j-1); qvpipe(j) := qvpipe(j-1); end loop; -- j eram_in(i).q <= qpipe(15); eram_in(i).qv <= qvpipe(15); elsif rising_edge(host_in.clk) then if host_in.extmem_bus.bank = i then if host_in.extmem_bus.gnt = '1' then ram_gnt(i) <= '1'; elsif host_in.extmem_bus.clrgnt = '1' then ram_gnt(i) <= '0'; elsif host_in.extmem_bus.wstb = '1' then mem_msw(host_in.extmem_bus.addr) := CONV_INTEGER(host_in.extmem_bus.data(63 downto 32)); mem_lsw(host_in.extmem_bus.addr) := CONV_INTEGER(host_in.extmem_bus.data(31 downto 0)); elsif host_in.extmem_bus.rstb = '1' then q(i) <= CONV_STD_LOGIC_VECTOR(mem_msw(host_in.extmem_bus.addr),32) & CONV_STD_LOGIC_VECTOR(mem_lsw(host_in.extmem_bus.addr),32); end if; end if; end if; end process model_ram; end generate connect_ram; process (host_in.extmem_bus.addr,q,host_in.clk) begin -- process host_out.extmem_bus.data <= q(host_in.extmem_bus.bank); if rising_edge(host_in.clk) then host_out.extmem_bus.req <= eram_out(host_in.extmem_bus.bank).req; end if; end process; end behave;