OpenCores
URL https://opencores.org/ocsvn/ax4lbr/ax4lbr/trunk

Subversion Repositories ax4lbr

[/] [ax4lbr/] [trunk/] [rtl/] [axil2wb.vhd] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wzab
-------------------------------------------------------------------------------
2 5 wzab
-- File       : axil2ipb.vhd
3
-- Author     : Wojciech M. Zabolotny  <wojciech.zabolotny@pw.edu.pl>
4
--              (with significant support of ChatGPT)
5 10 wzab
--            : some corrections by Marek Guminski 
6 2 wzab
-- Company    : Institute of Electronic Systems, Warsaw University of Technology
7 5 wzab
-- Created    : 2026-01-10
8 8 wzab
-- Last update: 2026-02-27
9 5 wzab
-- License    : This work is released into the public domain under
10
--              Creative Commons CC0 1.0 Universal (CC0 1.0) License.
11
--              https://creativecommons.org/publicdomain/zero/1.0/
12 2 wzab
-- Platform   : 
13
-- Standard   : VHDL'93/02
14
-------------------------------------------------------------------------------
15
-- Description: AXI Lite -> WB bridge
16 5 wzab
-- This is an improved and cleaned-up version of the simple AXI-Lite to Wishbone
17
-- bridge originally published on OpenCores
18
-- The modification was significantly supported by ChatGPT.
19
-- Therefore the solution is released to public domain.
20 2 wzab
-------------------------------------------------------------------------------
21 5 wzab
-- Copyright (c) 2026 
22 2 wzab
-------------------------------------------------------------------------------
23
-- Revisions  :
24 5 wzab
-- Date        Version  Author          Description
25
-- 2026-01-10  1.0      WZab+ChatGPT    Created
26 2 wzab
 
27 10 wzab
 
28 5 wzab
library ieee;
29
use ieee.std_logic_1164.all;
30
use ieee.numeric_std.all;
31 2 wzab
 
32
entity axil2wb is
33
  generic (
34 5 wzab
    ADRWIDTH          : integer := 32;
35
    DATAWIDTH         : integer := 32;
36 10 wzab
    WB_TIMEOUT_CYCLES : integer := 256;
37
    SYNC_RESET        : boolean := true;
38
    MASK_ERRORS       : boolean := true
39 5 wzab
    );
40
  port (
41
    -- AXI4-Lite
42
    S_AXI_ACLK    : in std_logic;
43
    S_AXI_ARESETN : in std_logic;
44 2 wzab
 
45
    S_AXI_AWADDR  : in  std_logic_vector(ADRWIDTH-1 downto 0);
46
    S_AXI_AWVALID : in  std_logic;
47
    S_AXI_AWREADY : out std_logic;
48 5 wzab
 
49
    S_AXI_WDATA  : in  std_logic_vector(31 downto 0);
50
    S_AXI_WSTRB  : in  std_logic_vector(3 downto 0);
51
    S_AXI_WVALID : in  std_logic;
52
    S_AXI_WREADY : out std_logic;
53
 
54
    S_AXI_BRESP  : out std_logic_vector(1 downto 0);
55
    S_AXI_BVALID : out std_logic;
56
    S_AXI_BREADY : in  std_logic;
57
 
58 2 wzab
    S_AXI_ARADDR  : in  std_logic_vector(ADRWIDTH-1 downto 0);
59
    S_AXI_ARVALID : in  std_logic;
60
    S_AXI_ARREADY : out std_logic;
61 5 wzab
 
62
    S_AXI_RDATA  : out std_logic_vector(31 downto 0);
63
    S_AXI_RRESP  : out std_logic_vector(1 downto 0);
64
    S_AXI_RVALID : out std_logic;
65
    S_AXI_RREADY : in  std_logic;
66
 
67
    -- Wishbone master
68
    wb_clk_o  : out std_logic;
69
    wb_rst_o  : out std_logic;
70
    wb_addr_o : out std_logic_vector(31 downto 0);
71
    wb_dat_o  : out std_logic_vector(31 downto 0);
72
    wb_dat_i  : in  std_logic_vector(31 downto 0);
73
    wb_we_o   : out std_logic;
74
    wb_sel_o  : out std_logic_vector(3 downto 0);
75
    wb_stb_o  : out std_logic;
76
    wb_cyc_o  : out std_logic;
77
    wb_ack_i  : in  std_logic;
78
    wb_err_i  : in  std_logic
79 2 wzab
    );
80 5 wzab
end entity;
81 2 wzab
 
82 5 wzab
architecture rtl of axil2wb is
83 2 wzab
 
84 10 wzab
  type state_t is (RST, IDLE, WB_READ, WB_WRITE, AXI_RSP);
85 5 wzab
  signal state : state_t := IDLE;
86 2 wzab
 
87 5 wzab
  signal S_AXI_AWREADY_s : std_logic := '0';
88
  signal S_AXI_ARREADY_s : std_logic := '0';
89
  signal S_AXI_WREADY_s  : std_logic := '0';
90 2 wzab
 
91 5 wzab
  signal aw_addr_r : std_logic_vector(ADRWIDTH-1 downto 0);
92 8 wzab
  signal ar_addr_r : std_logic_vector(ADRWIDTH-1 downto 0);
93 5 wzab
  signal w_data_r  : std_logic_vector(31 downto 0);
94 2 wzab
 
95 8 wzab
  signal aw_seen, w_seen, ar_seen      : std_logic := '0';
96
  signal write_ongoing                 : std_logic := '0';
97
  signal s_rst_n, s_rst_n_0, s_rst_n_1 : std_logic := '0';
98 2 wzab
 
99 5 wzab
  signal timeout_cnt : integer range 0 to WB_TIMEOUT_CYCLES;
100
 
101
begin
102
 
103 2 wzab
  wb_clk_o <= S_AXI_ACLK;
104 8 wzab
  wb_rst_o <= not s_rst_n;
105 5 wzab
  wb_sel_o <= (others => '1');
106 2 wzab
 
107 10 wzab
  is_sync_reset : if SYNC_RESET generate
108
    -- Synchronize the reset signal
109
    process(S_AXI_ACLK,S_AXI_ARESETN)
110
    begin
111 9 wzab
      if S_AXI_ARESETN = '0' then
112
        s_rst_n_0 <= '0';
113
        s_rst_n_1 <= '0';
114
        s_rst_n   <= '0';
115 10 wzab
      elsif rising_edge(S_AXI_ACLK) then
116 9 wzab
        s_rst_n_0 <= S_AXI_ARESETN;
117
        s_rst_n_1 <= s_rst_n_0;
118
        s_rst_n   <= s_rst_n_1;
119
      end if;
120 10 wzab
    end process;
121
  end generate is_sync_reset;
122 8 wzab
 
123 10 wzab
  not_sync_reset : if not SYNC_RESET generate
124
    s_rst_n <= S_AXI_ARESETN;
125
  end generate not_sync_reset;
126
 
127 5 wzab
  -- AXI READY (deterministic!)
128 8 wzab
  S_AXI_AWREADY_s <= '1' when (state = IDLE and aw_seen = '0' and ar_seen = '0')                  else '0';
129
  S_AXI_WREADY_s  <= '1' when (state = IDLE and w_seen = '0' and ar_seen = '0')                   else '0';
130
  S_AXI_ARREADY_s <= '1' when (state = IDLE and ar_seen = '0' and w_seen = '0' and aw_seen = '0') else '0';
131 2 wzab
 
132 5 wzab
  S_AXI_AWREADY <= S_AXI_AWREADY_s;
133
  S_AXI_WREADY  <= S_AXI_WREADY_s;
134
  S_AXI_ARREADY <= S_AXI_ARREADY_s;
135
 
136
  process (S_AXI_ACLK)
137
  begin
138
    if rising_edge(S_AXI_ACLK) then
139 8 wzab
      if s_rst_n = '0' then
140 10 wzab
        state         <= RST;
141 8 wzab
        aw_seen       <= '0';
142
        w_seen        <= '0';
143
        ar_seen       <= '0';
144
        wb_cyc_o      <= '0';
145
        wb_stb_o      <= '0';
146
        wb_we_o       <= '0';
147
        S_AXI_BVALID  <= '0';
148
        S_AXI_RVALID  <= '0';
149
        S_AXI_RDATA   <= (others => '0');
150
        S_AXI_BRESP   <= "00";
151
        S_AXI_RRESP   <= "00";
152
        timeout_cnt   <= 0;
153
        write_ongoing <= '0';
154 2 wzab
      else
155
 
156 5 wzab
        -- defaults
157
        S_AXI_BVALID <= '0';
158
        S_AXI_RVALID <= '0';
159
 
160
        case state is
161 10 wzab
          when RST =>
162
            state <= IDLE;
163 5 wzab
 
164
          when IDLE =>
165
            timeout_cnt <= 0;
166 7 wzab
            wb_cyc_o    <= '0';
167
            wb_stb_o    <= '0';
168
            wb_we_o     <= '0';
169 5 wzab
            if S_AXI_AWVALID = '1' and S_AXI_AWREADY_s = '1' then
170
              aw_addr_r <= S_AXI_AWADDR;
171
              aw_seen   <= '1';
172
            end if;
173
 
174
            if S_AXI_WVALID = '1' and S_AXI_WREADY_s = '1' then
175
              w_data_r <= S_AXI_WDATA;
176
              w_seen   <= '1';
177
            end if;
178
 
179 8 wzab
            if S_AXI_ARVALID = '1' and S_AXI_ARREADY_s = '1' then
180
              ar_seen   <= '1';
181
              -- Divide the address by 4 (in WB we use word not byte addressing)
182
              ar_addr_r <= S_AXI_ARADDR;
183
            end if;
184
 
185 5 wzab
            if aw_seen = '1' and w_seen = '1' then
186
              -- Divide the address by 4 (in WB we use word not byte addressing)
187
              wb_addr_o                      <= (others => '0');
188
              wb_addr_o(ADRWIDTH-3 downto 0) <= aw_addr_r(ADRWIDTH-1 downto 2);
189
              wb_dat_o                       <= w_data_r;
190
              wb_we_o                        <= '1';
191
              wb_cyc_o                       <= '1';
192
              wb_stb_o                       <= '1';
193 8 wzab
              write_ongoing                  <= '1';
194 5 wzab
              state                          <= WB_WRITE;
195 8 wzab
            elsif ar_seen = '1' then
196 5 wzab
              wb_addr_o                      <= (others => '0');
197 8 wzab
              wb_addr_o(ADRWIDTH-3 downto 0) <= ar_addr_r(ADRWIDTH-1 downto 2);
198 5 wzab
              wb_we_o                        <= '0';
199
              wb_cyc_o                       <= '1';
200
              wb_stb_o                       <= '1';
201 8 wzab
              write_ongoing                  <= '0';
202 5 wzab
              state                          <= WB_READ;
203
            end if;
204
 
205
          when WB_WRITE =>
206 9 wzab
            if timeout_cnt < WB_TIMEOUT_CYCLES then
207
              timeout_cnt <= timeout_cnt + 1;
208
            end if;
209 5 wzab
            if wb_ack_i = '1' or wb_err_i = '1' then
210
              wb_cyc_o <= '0';
211
              wb_stb_o <= '0';
212 7 wzab
              wb_we_o  <= '0';
213 5 wzab
              if wb_err_i = '1' then
214 10 wzab
                if MASK_ERRORS then
215
                  S_AXI_BRESP <= "00";
216
                else
217
                  S_AXI_BRESP <= "10";
218
                end if;
219 5 wzab
              else
220 7 wzab
                S_AXI_BRESP <= "00";
221 5 wzab
              end if;
222 7 wzab
              S_AXI_BVALID <= '1';
223
              state        <= AXI_RSP;
224 5 wzab
            elsif timeout_cnt = WB_TIMEOUT_CYCLES then
225 10 wzab
              wb_cyc_o <= '0';
226
              wb_stb_o <= '0';
227
              wb_we_o  <= '0';
228
              if MASK_ERRORS then
229
                S_AXI_BRESP <= "00";
230
              else
231
                S_AXI_BRESP <= "11";    -- timeout signalled as DECERR
232
              end if;
233 7 wzab
              S_AXI_BVALID <= '1';
234
              state        <= AXI_RSP;
235 5 wzab
            end if;
236
 
237
          when WB_READ =>
238 9 wzab
            if timeout_cnt < WB_TIMEOUT_CYCLES then
239
              timeout_cnt <= timeout_cnt + 1;
240
            end if;
241 5 wzab
            if wb_ack_i = '1' or wb_err_i = '1' then
242 7 wzab
              wb_cyc_o    <= '0';
243
              wb_stb_o    <= '0';
244
              wb_we_o     <= '0';
245
              S_AXI_RDATA <= wb_dat_i;
246 5 wzab
              if wb_err_i = '1' then
247 10 wzab
                if MASK_ERRORS then
248
                  S_AXI_RDATA <= x"deadbeaf";
249
                  S_AXI_RRESP <= "00";
250
                else
251
                  S_AXI_RRESP <= "10";
252
                end if;
253 7 wzab
                S_AXI_RVALID <= '1';
254 5 wzab
              else
255 7 wzab
                S_AXI_RRESP  <= "00";
256
                S_AXI_RVALID <= '1';
257 5 wzab
              end if;
258
              state <= AXI_RSP;
259
            elsif timeout_cnt = WB_TIMEOUT_CYCLES then
260 10 wzab
              wb_cyc_o <= '0';
261
              wb_stb_o <= '0';
262
              wb_we_o  <= '0';
263
              if MASK_ERRORS then
264
                S_AXI_RDATA <= x"deadbeaf";
265
                S_AXI_RRESP <= "00";
266
              else
267
                S_AXI_RRESP <= "11";    -- timeout signalled as DECERR
268
              end if;
269 7 wzab
              S_AXI_RVALID <= '1';
270
              state        <= AXI_RSP;
271 5 wzab
            end if;
272
 
273
          when AXI_RSP =>
274 8 wzab
            if write_ongoing = '1' then
275 5 wzab
              S_AXI_BVALID <= '1';
276
              if S_AXI_BREADY = '1' then
277 8 wzab
                S_AXI_BVALID  <= '0';
278
                aw_seen       <= '0';
279
                w_seen        <= '0';
280
                write_ongoing <= '0';
281
                state         <= IDLE;
282 5 wzab
              end if;
283
            else
284
              S_AXI_RVALID <= '1';
285
              if S_AXI_RREADY = '1' then
286
                S_AXI_RVALID <= '0';
287 7 wzab
                ar_seen      <= '0';
288
                state        <= IDLE;
289 5 wzab
              end if;
290
            end if;
291
 
292
        end case;
293 2 wzab
      end if;
294
    end if;
295
  end process;
296
 
297 5 wzab
end architecture;
298 7 wzab
 

powered by: WebSVN 2.1.0

© copyright 1999-2026 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.