-- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- -- TODO -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library generics; use generics.wishbone_pkg.all; entity aps6404l_wb is port( clk : in std_logic; rst : in std_logic; -- -- Wishbone IF wb_o : out wishbone_slave_out; -- Wishbone bus (out) wb_i : in wishbone_slave_in; -- Wishbone bus (in) -- PSRAM IF psram_ce_n : out std_logic; psram_sclk : out std_logic; psram_sio : inout std_logic_vector(3 downto 0) -- ); end entity aps6404l_wb; architecture rtl of aps6404l_wb is signal apsc_addr : std_logic_vector(23 downto 0); signal apsc_data_in : std_logic_vector(7 downto 0); signal apsc_data_in_next : std_logic; signal apsc_data_out : std_logic_vector(7 downto 0); signal apsc_data_out_valid : std_logic; signal apsc_write_en : std_logic; signal apsc_read_en : std_logic; signal bit_cnt : integer range 0 to 4; signal data : std_logic_vector(wb_i.dat'range); begin aps6404l_controller_inst : entity work.aps6404l_controller port map( clk => clk, rst => rst, addr => apsc_addr, data_in => apsc_data_in, data_in_next => apsc_data_in_next, data_out => apsc_data_out, data_out_valid => apsc_data_out_valid, write_en => apsc_write_en, read_en => apsc_read_en, psram_ce_n => psram_ce_n, psram_sclk => psram_sclk, psram_sio => psram_sio ); main : process(clk, rst) is variable start_addr : integer range 0 to 3; variable stop_addr : integer range 0 to 3; variable success : std_logic; begin if rst then wb_o.ack <= '0'; bit_cnt <= 0; elsif rising_edge(clk) then wb_o.ack <= '0'; if bit_cnt = 0 then apsc_read_en <= '0'; apsc_write_en <= '0'; start_addr := 0; for i in 0 to 3 loop if wb_i.sel(i) = '1' then start_addr := i; exit; end if; end loop; stop_addr := 0; for i in 3 downto 0 loop if wb_i.sel(i) = '1' then stop_addr := i; exit; end if; end loop; apsc_addr <= wb_i.adr(apsc_addr'length - 1 downto 2) & std_logic_vector(to_unsigned(start_addr, 2)); data <= wb_i.dat; if not wb_o.ack and wb_i.stb and wb_i.cyc then bit_cnt <= 4; end if; else success := '0'; if bit_cnt >= (4 - stop_addr) and bit_cnt <= (4 - start_addr) then apsc_read_en <= not wb_i.we; apsc_write_en <= wb_i.we; else apsc_read_en <= '0'; apsc_write_en <= '0'; success := '1'; end if; if wb_i.we and apsc_data_in_next then success := '1'; elsif not wb_i.we and apsc_data_out_valid then success := '1'; end if; if success then bit_cnt <= bit_cnt - 1; wb_o.dat <= apsc_data_out & wb_o.dat(wb_o.dat'high downto 8); data <= x"--" & data(data'high downto 8); if bit_cnt = 1 then wb_o.ack <= '1'; end if; end if; end if; end if; end process main; apsc_data_in <= data(apsc_data_in'range); wb_o.err <= '0'; wb_o.rty <= '0'; wb_o.stall <= not wb_o.ack; end architecture rtl;