blob: 3ec84543f83ac9f6ac6e4debfc58a9cbfbfb700e (
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axi_regfile is
generic (
NUM_REGS : integer := 16
);
port (
regs : out std_logic_vector(NUM_REGS*32-1 downto 0);
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
S_AXI_AWADDR : in std_logic_vector(11 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_AWREADY : out std_logic;
S_AXI_WDATA : in std_logic_vector(31 downto 0);
S_AXI_WSTRB : in std_logic_vector(3 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_WREADY : out std_logic;
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_BREADY : in std_logic;
S_AXI_ARADDR : in std_logic_vector(11 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_RDATA : out std_logic_vector(31 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_RREADY : in std_logic
);
end axi_regfile;
architecture arch of axi_regfile is
type regfile_t is array (integer range <>) of std_logic_vector(31 downto 0);
signal read_token : std_logic;
signal write_addr : std_logic_vector(S_AXI_AWADDR'left downto S_AXI_AWADDR'right);
signal write_strb : std_logic_vector(3 downto 0);
signal write_addr_token : std_logic;
signal write_data : std_logic_vector(31 downto 0);
signal write_data_token : std_logic;
signal soft_reset : std_logic;
signal regs_r : regfile_t(NUM_REGS-1 downto 0);
begin
S_AXI_ARREADY <= not read_token;
S_AXI_RVALID <= read_token;
S_AXI_RRESP <= "00";
S_AXI_AWREADY <= not write_addr_token;
S_AXI_WREADY <= not write_data_token;
S_AXI_BVALID <= write_addr_token and write_data_token;
S_AXI_BRESP <= "00";
--Port assignment from registers
reg_distribution : process (regs_r)
begin
for i in 0 to NUM_REGS-1 loop
regs(32*(i+1)-1 downto 32*i) <= regs_r(i);
end loop;
end process reg_distribution;
--Register reads
read_proc : process (S_AXI_ACLK)
variable read_addr : integer;
begin
if rising_edge(S_AXI_ACLK) then
read_addr := to_integer(unsigned(S_AXI_ARADDR(S_AXI_ARADDR'left downto S_AXI_ARADDR'right+2)));
if (S_AXI_ARESETN = '0') then
read_token <= '0';
elsif (S_AXI_ARVALID = '1') and (read_token = '0') then
read_token <= '1';
elsif (S_AXI_RREADY = '1') and (read_token = '1') then
read_token <= '0';
end if;
if (S_AXI_ARVALID = '1') and (read_token = '0') then
S_AXI_RDATA <= (others => '0');
for i in 0 to NUM_REGS-1 loop
if (read_addr = i) then
S_AXI_RDATA <= regs_r(i);
end if;
end loop;
end if;
end if;
end process read_proc;
write_proc : process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if (S_AXI_ARESETN = '0') then
write_addr_token <= '0';
write_data_token <= '0';
write_strb <= (others => '0');
else
if (S_AXI_AWVALID = '1') and (write_addr_token = '0') then
write_addr_token <= '1';
elsif (S_AXI_BREADY = '1') and (write_addr_token = '1') and (write_data_token = '1') then
write_addr_token <= '0';
end if;
if (S_AXI_WVALID = '1') and (write_data_token = '0') then
write_data_token <= '1';
elsif (S_AXI_BREADY = '1') and (write_addr_token = '1') and (write_data_token = '1') then
write_data_token <= '0';
end if;
end if;
if (S_AXI_AWVALID = '1') and (write_addr_token = '0') then
write_addr <= S_AXI_AWADDR;
end if;
if (S_AXI_WVALID = '1') and (write_data_token = '0') then
write_data <= S_AXI_WDATA;
write_strb <= S_AXI_WSTRB;
end if;
end if;
end process write_proc;
-- Update registers on write
write_reg : process (S_AXI_ACLK)
variable write_addr_int : integer;
begin
if rising_edge(S_AXI_ACLK) then
write_addr_int := to_integer(unsigned(write_addr(write_addr'left downto 2)));
if (S_AXI_ARESETN = '0') or (soft_reset = '1') then
--Initial states for each signal
soft_reset <= '0';
elsif (write_addr_token = '1') and (write_data_token = '1') then
for i in 0 to NUM_REGS-1 loop
if (write_addr_int = i) then
for j in write_strb'left downto write_strb'right loop
regs_r(i)(j*8+7 downto j*8) <= write_data(j*8+7 downto j*8);
end loop;
end if;
end loop;
end if;
end if;
end process write_reg;
end arch;
|