--====================================================================== library ieee; use ieee.std_logic_1164.all; use work.ipbus.all; use work.ipbus_reg_types.all; library unisim; use unisim.vcomponents.all; use work.ipbus_decode_flash_interface.all; --================================================== entity dth_flash_interface is port ( -- IPbus interface. clk : in std_logic; rst : in std_logic; ipb_in : in ipb_wbus; ipb_out : out ipb_rbus; -- AXI clock. axi_aclk : in std_logic; -- Flash interface. flash_data : inout std_logic_vector(15 downto 4); flash_add : out std_logic_vector(31 downto 0); flash_oen : out std_logic; flash_wen : out std_logic ); end dth_flash_interface; --================================================== architecture rtl of dth_flash_interface is -- IPBus read/write buses. signal ipbw : ipb_wbus_array(N_SLAVES - 1 downto 0); signal ipbr : ipb_rbus_array(N_SLAVES - 1 downto 0); signal axi_reset : std_logic; signal axi_resetn : std_logic; signal axi_mem_awaddr : std_logic_vector(31 downto 0); signal axi_mem_awvalid : std_logic; signal axi_mem_awready : std_logic; signal axi_mem_wdata : std_logic_vector(31 downto 0); signal axi_mem_wstrb : std_logic_vector(3 downto 0); signal axi_mem_size : std_logic_vector(2 downto 0); signal axi_mem_wvalid : std_logic; signal axi_mem_wready : std_logic; signal axi_mem_bvalid : std_logic; signal axi_mem_bready : std_logic; signal axi_mem_araddr : std_logic_vector(31 downto 0); signal axi_mem_arvalid : std_logic; signal axi_mem_arready : std_logic; signal axi_mem_rdata : std_logic_vector(31 downto 0); signal axi_mem_rvalid : std_logic; signal axi_mem_rready : std_logic; signal flash_data_out : std_logic_vector(15 downto 0); signal flash_data_tristate : std_logic_vector(15 downto 0); signal flash_data_in_startup : std_logic_vector(3 downto 0); signal flash_data_tristate_startup : std_logic_vector(3 downto 0); signal flash_data_out_startup : std_logic_vector(3 downto 0); signal flash_cen : std_logic; begin -- IPBus address decoder. fabric : entity work.ipbus_fabric_sel generic map ( NSLV => N_SLAVES, SEL_WIDTH => IPBUS_SEL_WIDTH ) port map ( ipb_in => ipb_in, ipb_out => ipb_out, sel => ipbus_sel_flash_interface(ipb_in.ipb_addr), ipb_to_slaves => ipbw, ipb_from_slaves => ipbr ); ------------------------------------------ cdc_reset : entity work.cdc_reset port map ( reset_in => rst, clk_dst => axi_aclk, reset_out => axi_reset ); axi_resetn <= not axi_reset; ------------------------------------------ -- The bridge from IPbus to AXI4Lite master. ipbus_to_axi_bridge : entity work.ipbus_axi_bridge port map ( -- IPbus side. clk => clk, rst => rst, ipb_in => ipbw(N_SLV_AXI_BRIDGE), ipb_out => ipbr(N_SLV_AXI_BRIDGE), -- AXI side. m_axi_clock => axi_aclk, m_axi_awaddr => axi_mem_awaddr, m_axi_awvalid => axi_mem_awvalid, m_axi_awready => axi_mem_awready, m_axi_wdata => axi_mem_wdata, m_axi_wstrb => axi_mem_wstrb, m_axi_size => axi_mem_size, m_axi_wvalid => axi_mem_wvalid, m_axi_wready => axi_mem_wready, m_axi_bresp => "00", m_axi_bvalid => axi_mem_bvalid, m_axi_bready => axi_mem_bready, m_axi_araddr => axi_mem_araddr, m_axi_arvalid => axi_mem_arvalid, m_axi_arready => axi_mem_arready, m_axi_rdata => axi_mem_rdata, m_axi_rvalid => axi_mem_rvalid, m_axi_rresp => "00", m_axi_rready => axi_mem_rready ); ------------------------------------------ -- An intermediate buffer for writes into the flash. This allows us -- to do (reasonably efficient) block transfers into here, and then -- (reasonably fast) internal writes to the flash itself (instead of -- a terrifyingly slow series of single-register accesses all the -- way through to the flash). write_buffer : entity work.ipbus_ported_dpram generic map ( ADDR_WIDTH => 16, DATA_WIDTH => 32 ) port map ( clk => clk, rst => rst, ipb_in => ipbw(N_SLV_WRITE_BUFFER), ipb_out => ipbr(N_SLV_WRITE_BUFFER), rclk => '0', --: in std_logic; we => '0', d => (others => '0'), --: in std_logic_vector(31 downto 0) q => open, --: out std_logic_vector(31 downto 0) addr => (others => '0') --: in std_logic_vector(15 downto 0) ); ------------------------------------------ -- The STARTUPE3 primitive gives us access to the FPGA -- PROM/configuration pins. startup : STARTUPE3 generic map ( PROG_USR => "FALSE" ) port map ( cfgclk => open, cfgmclk => open, di => flash_data_in_startup, eos => open, --flash_eos, preq => open, do => flash_data_out_startup, dts => flash_data_tristate_startup, fcsbo => flash_cen, fcsbts => '0', gsr => '0', gts => '0', keyclearb => '1', pack => '1', usrcclko => '0', usrcclkts => '0', usrdoneo => '1', usrdonets => '1' ); ------------------------------------------ -- The external memory controller gives us access to the PROM holding -- the FPGA image. flash_controller : entity work.axi_emc_flash_controller port map ( s_axi_aclk => axi_aclk, s_axi_aresetn => axi_resetn, rdclk => axi_aclk, s_axi_mem_awid => "0000", s_axi_mem_awaddr => axi_mem_awaddr, s_axi_mem_awlen => "00000000", s_axi_mem_awsize => axi_mem_size, s_axi_mem_awburst => "01", s_axi_mem_awlock => '0', s_axi_mem_awcache => "0000", s_axi_mem_awprot => "000", s_axi_mem_awvalid => axi_mem_awvalid, s_axi_mem_awready => axi_mem_awready, s_axi_mem_wdata => axi_mem_wdata, s_axi_mem_wstrb => axi_mem_wstrb, s_axi_mem_wlast => '1', s_axi_mem_wvalid => axi_mem_wvalid, s_axi_mem_wready => axi_mem_wready, s_axi_mem_bvalid => axi_mem_bvalid, s_axi_mem_bready => axi_mem_bready, s_axi_mem_arid => "0000", s_axi_mem_araddr => axi_mem_araddr, s_axi_mem_arlen => "00000000", s_axi_mem_arsize => axi_mem_size, s_axi_mem_arburst => "01", s_axi_mem_arlock => '0', s_axi_mem_arcache => "0000", s_axi_mem_arprot => "000", s_axi_mem_arvalid => axi_mem_arvalid, s_axi_mem_arready => axi_mem_arready, s_axi_mem_rdata => axi_mem_rdata, s_axi_mem_rvalid => axi_mem_rvalid, s_axi_mem_rready => axi_mem_rready, mem_dq_i(15 downto 4) => flash_data(15 downto 4), mem_dq_i(3 downto 0) => flash_data_in_startup(3 downto 0), mem_dq_o(15 downto 4) => flash_data_out(15 downto 4), mem_dq_o(3 downto 0) => flash_data_out_startup, mem_dq_t(15 downto 4) => flash_data_tristate(15 downto 4), mem_dq_t(3 downto 0) => flash_data_tristate_startup, mem_a(31 downto 0) => flash_add, mem_cen(0) => flash_cen, mem_oen(0) => flash_oen, mem_wen => flash_wen, mem_wait(0) => '0' ); ------------------------------------------ flash_data_bus : for i in 4 to 15 generate flash_data(i) <= flash_data_out(i) when flash_data_tristate(i) = '0' else 'Z'; end generate; end rtl; --======================================================================