137 lines
3.6 KiB
VHDL
137 lines
3.6 KiB
VHDL
-- -------------------------------------------------------------------------- --
|
|
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
|
-- -------------------------------------------------------------------------- --
|
|
-- TODO
|
|
-- -------------------------------------------------------------------------- --
|
|
-- Author : Markus Koch <markus@notsyncing.net>
|
|
-- 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;
|