blob: c527ea1550d331185786b986c224252a6f7d5f5f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity fifo_to_axi is
generic (
ADDR_WIDTH : integer := 32;
START : unsigned(31 downto 0) := x"FFFC0000";
SIZE : unsigned(31 downto 0) := x"00040000"
);
port (
aclk : in std_logic;
aresetn : in std_logic;
run : in std_logic;
fifo_empty : in std_logic;
fifo_rdata : in std_logic_vector(64 downto 0);
fifo_rd_en : out std_logic;
axi_awaddr : out std_logic_vector (ADDR_WIDTH-1 downto 0);
axi_awvalid : out std_logic;
axi_awready : in std_logic;
axi_wdata : out std_logic_vector (63 downto 0);
axi_wstrb : out std_logic_vector (7 downto 0);
axi_wvalid : out std_logic;
axi_wready : in std_logic;
axi_bvalid : in std_logic;
axi_bready : out std_logic
);
end entity fifo_to_axi;
architecture Behavioral of fifo_to_axi is
--signal lazy : std_logic_vector(63 downto 0);
signal addr : std_logic_vector(ADDR_WIDTH-1 downto 0) := std_logic_vector(START);
signal data : std_logic_vector(63 downto 0);
signal do_bus_cycle : std_logic;
signal s_run : std_logic;
begin
run_sync : entity work.synchronizer
generic map(stages => 2)
port map (
clk => aclk,
i => run,
o => s_run
);
axi_bready <= do_bus_cycle;
axi_wdata <= data;
axi_wstrb <= (others => '1');
axi_awaddr <= addr;
--XXX this is moderately budget, it could do with a tonne of pipelining
process (aclk)
begin
if rising_edge(aclk) then
if aresetn = '0' then
axi_awvalid <= '0';
axi_wvalid <= '0';
do_bus_cycle <= '0';
fifo_rd_en <= '0';
addr <= std_logic_vector(START);
elsif run = '1' and do_bus_cycle = '1' then
fifo_rd_en <= '0';
if axi_bvalid = '1' then
do_bus_cycle <= '0';
if addr /= std_logic_vector(START+SIZE-to_unsigned(8, ADDR_WIDTH)) then
addr <= std_logic_vector(unsigned(addr) +to_unsigned(8, ADDR_WIDTH));
end if;
axi_awvalid <= '0';
axi_wvalid <= '0';
end if;
if axi_awready = '1' then
axi_awvalid <= '0';
end if;
if axi_wready = '1' then
axi_wvalid <= '0';
end if;
elsif do_bus_cycle = '0' then
if fifo_empty = '0' then
data <= fifo_rdata (63 downto 0);
if fifo_rdata(64) = '1' then
addr <= std_logic_vector(START);
end if;
fifo_rd_en <= '1';
do_bus_cycle <= '1';
axi_awvalid <= '1';
axi_wvalid <= '1';
end if;
end if;
end if;
end process;
end Behavioral;
|