Skip to content

Commit 40ddbc6

Browse files
authored
[rtl/system_integration] create individual module for AXI4 Lite bridge (#1063)
2 parents 54bb301 + c65af0c commit 40ddbc6

File tree

6 files changed

+280
-106
lines changed

6 files changed

+280
-106
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
2929

3030
| Date | Version | Comment | Ticket |
3131
|:----:|:-------:|:--------|:------:|
32+
| 18.10.2024 | 1.10.5.7 | use individual/new module for XBUS-to-AXI4-Lite bridge | [#](https://github.com/stnolting/neorv32/pull/1063) |
3233
| 12.10.2024 | 1.10.5.6 | :warning: remove legacy support for on-chip debugger DM version v0.13; now only supporting DM v1.0 (removing `OCD_DM_LEGACY_MODE` generic) | [#1056](https://github.com/stnolting/neorv32/pull/1056) |
3334
| 11.10.2024 | 1.10.5.5 | :sparkles: :lock: add support for optional on-chip debugger authentication; :warning: rename OCD-related top generics | [#1053](https://github.com/stnolting/neorv32/pull/1053) |
3435
| 06.10.2024 | 1.10.5.4 | :warning: rework PWM module | [#1049](https://github.com/stnolting/neorv32/pull/1049) |

docs/datasheet/soc_xbus.adoc

+2-3
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ see section <<_address_space>>) are **redirected** to the external bus interface
4444

4545
.AXI4-Lite Interface Bridge
4646
[TIP]
47-
A processor top entity with an AXI4-Lite-compatible bus interface can be found in `rtl/system_inegration`.
48-
More information regarding this alternate top entity can be found in in the user guide:
49-
https://stnolting.github.io/neorv32/ug/#_packaging_the_processor_as_vivado_ip_block
47+
A simple bridge that converts the processor's XBUS into an AXI4-lite-compatible host interface can
48+
be found in in `rtl/system_inegration` (`xbus2axi4lite_bridge.vhd`).
5049

5150
.AHB3-Lite Interface Bridge
5251
[TIP]

rtl/core/neorv32_package.vhd

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ package neorv32_package is
2929

3030
-- Architecture Constants -----------------------------------------------------------------
3131
-- -------------------------------------------------------------------------------------------
32-
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100506"; -- hardware version
32+
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100507"; -- hardware version
3333
constant archid_c : natural := 19; -- official RISC-V architecture ID
3434
constant XLEN : natural := 32; -- native data path width
3535

rtl/system_integration/neorv32_vivado_ip.tcl

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ puts $file_list
4848
add_files $file_list
4949
set_property library neorv32 [get_files $file_list]
5050

51-
# IP top module
51+
# IP top module and AXI4-Lite bridge
52+
add_file $neorv32_home/rtl/system_integration/xbus2axi4lite_bridge.vhd
5253
add_file $neorv32_home/rtl/system_integration/$ip_top.vhd
5354
set_property top $ip_top [current_fileset]
5455

rtl/system_integration/neorv32_vivado_ip.vhd

+122-101
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,60 @@ architecture neorv32_vivado_ip_rtl of neorv32_vivado_ip is
256256
constant num_xirq_c : natural := cond_sel_natural_f(XIRQ_EN, XIRQ_NUM_CH, 0);
257257
constant num_pwm_c : natural := cond_sel_natural_f(IO_PWM_EN, IO_PWM_NUM_CH, 0);
258258

259+
-- AXI4-Lite bridge --
260+
component xbus2axi4lite_bridge
261+
port (
262+
-- ------------------------------------------------------------
263+
-- Global Control
264+
-- ------------------------------------------------------------
265+
clk : in std_logic;
266+
resetn : in std_logic; -- low-active
267+
-- ------------------------------------------------------------
268+
-- XBUS Device Interface
269+
-- ------------------------------------------------------------
270+
xbus_adr_i : in std_ulogic_vector(31 downto 0); -- address
271+
xbus_dat_i : in std_ulogic_vector(31 downto 0); -- write data
272+
xbus_tag_i : in std_ulogic_vector(2 downto 0); -- access tag
273+
xbus_we_i : in std_ulogic; -- read/write
274+
xbus_sel_i : in std_ulogic_vector(3 downto 0); -- byte enable
275+
xbus_stb_i : in std_ulogic; -- strobe
276+
xbus_cyc_i : in std_ulogic; -- valid cycle
277+
xbus_ack_o : out std_ulogic; -- transfer acknowledge
278+
xbus_err_o : out std_ulogic; -- transfer error
279+
xbus_dat_o : out std_ulogic_vector(31 downto 0); -- read data
280+
-- ------------------------------------------------------------
281+
-- AXI4-Lite Host Interface
282+
-- ------------------------------------------------------------
283+
-- Clock and Reset --
284+
-- m_axi_aclk : in std_logic := '0'; -- just to satisfy Vivado, but not actually used
285+
-- m_axi_aresetn : in std_logic := '0'; -- just to satisfy Vivado, but not actually used
286+
-- Write Address Channel --
287+
m_axi_awaddr : out std_logic_vector(31 downto 0);
288+
m_axi_awprot : out std_logic_vector(2 downto 0);
289+
m_axi_awvalid : out std_logic;
290+
m_axi_awready : in std_logic := '0';
291+
-- Write Data Channel --
292+
m_axi_wdata : out std_logic_vector(31 downto 0);
293+
m_axi_wstrb : out std_logic_vector(3 downto 0);
294+
m_axi_wvalid : out std_logic;
295+
m_axi_wready : in std_logic := '0';
296+
-- Read Address Channel --
297+
m_axi_araddr : out std_logic_vector(31 downto 0);
298+
m_axi_arprot : out std_logic_vector(2 downto 0);
299+
m_axi_arvalid : out std_logic;
300+
m_axi_arready : in std_logic := '0';
301+
-- Read Data Channel --
302+
m_axi_rdata : in std_logic_vector(31 downto 0) := x"00000000";
303+
m_axi_rresp : in std_logic_vector(1 downto 0) := "11"; -- error by default
304+
m_axi_rvalid : in std_logic := '0';
305+
m_axi_rready : out std_logic;
306+
-- Write Response Channel --
307+
m_axi_bresp : in std_logic_vector(1 downto 0) := "11"; -- error by default
308+
m_axi_bvalid : in std_logic := '0';
309+
m_axi_bready : out std_logic
310+
);
311+
end component;
312+
259313
-- type conversion --
260314
signal jtag_tdo_aux : std_ulogic;
261315
signal s0_axis_tdata_aux : std_ulogic_vector(31 downto 0);
@@ -279,21 +333,16 @@ architecture neorv32_vivado_ip_rtl of neorv32_vivado_ip is
279333
signal xirq_i_aux : std_ulogic_vector(31 downto 0);
280334

281335
-- internal wishbone bus --
282-
type wb_bus_t is record
283-
adr : std_ulogic_vector(31 downto 0);
284-
di : std_ulogic_vector(31 downto 0);
285-
do : std_ulogic_vector(31 downto 0);
286-
tag : std_ulogic_vector(2 downto 0);
287-
we : std_ulogic;
288-
sel : std_ulogic_vector(3 downto 0);
289-
cyc : std_ulogic;
290-
ack : std_ulogic;
291-
err : std_ulogic;
292-
end record;
293-
signal wb_core : wb_bus_t;
294-
295-
-- AXI bridge control --
296-
signal axi_radr_received, axi_wadr_received, axi_wdat_received : std_ulogic;
336+
signal xbus_adr : std_ulogic_vector(31 downto 0); -- address
337+
signal xbus_do : std_ulogic_vector(31 downto 0); -- write data
338+
signal xbus_tag : std_ulogic_vector(2 downto 0); -- access tag
339+
signal xbus_we : std_ulogic; -- read/write
340+
signal xbus_sel : std_ulogic_vector(3 downto 0); -- byte enable
341+
signal xbus_stb : std_ulogic; -- strobe
342+
signal xbus_cyc : std_ulogic; -- valid cycle
343+
signal xbus_di : std_ulogic_vector(31 downto 0); -- read data
344+
signal xbus_ack : std_ulogic; -- transfer acknowledge
345+
signal xbus_err : std_ulogic; -- transfer error
297346

298347
begin
299348

@@ -416,16 +465,16 @@ begin
416465
jtag_tdo_o => jtag_tdo_aux,
417466
jtag_tms_i => std_ulogic(jtag_tms_i),
418467
-- External bus interface (available if XBUS_EN = true) --
419-
xbus_adr_o => wb_core.adr,
420-
xbus_dat_o => wb_core.do,
421-
xbus_tag_o => wb_core.tag,
422-
xbus_we_o => wb_core.we,
423-
xbus_sel_o => wb_core.sel,
424-
xbus_stb_o => open,
425-
xbus_cyc_o => wb_core.cyc,
426-
xbus_dat_i => wb_core.di,
427-
xbus_ack_i => wb_core.ack,
428-
xbus_err_i => wb_core.err,
468+
xbus_adr_o => xbus_adr,
469+
xbus_dat_o => xbus_do,
470+
xbus_tag_o => xbus_tag,
471+
xbus_we_o => xbus_we,
472+
xbus_sel_o => xbus_sel,
473+
xbus_stb_o => xbus_stb,
474+
xbus_cyc_o => xbus_cyc,
475+
xbus_dat_i => xbus_di,
476+
xbus_ack_i => xbus_ack,
477+
xbus_err_i => xbus_err,
429478
-- Stream Link Interface (available if IO_SLINK_EN = true) --
430479
slink_rx_dat_i => std_ulogic_vector(s1_axis_tdata),
431480
slink_rx_src_i => std_ulogic_vector(s1_axis_tid),
@@ -564,81 +613,53 @@ begin
564613

565614
-- Wishbone-to-AXI4-Lite Bridge -----------------------------------------------------------
566615
-- -------------------------------------------------------------------------------------------
567-
axi_arbiter: process(resetn, clk)
568-
begin
569-
if (resetn = '0') then
570-
axi_radr_received <= '0';
571-
axi_wadr_received <= '0';
572-
axi_wdat_received <= '0';
573-
elsif rising_edge(clk) then
574-
if (wb_core.cyc = '0') then
575-
axi_radr_received <= '0';
576-
axi_wadr_received <= '0';
577-
axi_wdat_received <= '0';
578-
else -- pending access
579-
if (wb_core.we = '0') then -- read
580-
if (m_axi_arready = '1') then -- read address received by interconnect?
581-
axi_radr_received <= '1';
582-
end if;
583-
else -- write
584-
if (m_axi_awready = '1') then -- write address received by interconnect?
585-
axi_wadr_received <= '1';
586-
end if;
587-
if (m_axi_wready = '1') then -- write data received by interconnect?
588-
axi_wdat_received <= '1';
589-
end if;
590-
end if;
591-
end if;
592-
end if;
593-
end process axi_arbiter;
594-
595-
596-
-- read address channel --
597-
m_axi_araddr <= std_logic_vector(wb_core.adr);
598-
m_axi_arprot <= std_logic_vector(wb_core.tag);
599-
m_axi_arvalid <= std_logic(wb_core.cyc and (not wb_core.we) and (not axi_radr_received));
600-
601-
-- read data channel --
602-
m_axi_rready <= std_logic(wb_core.cyc and (not wb_core.we));
603-
wb_core.di <= std_ulogic_vector(m_axi_rdata);
604-
605-
-- write address channel --
606-
m_axi_awaddr <= std_logic_vector(wb_core.adr);
607-
m_axi_awprot <= std_logic_vector(wb_core.tag);
608-
m_axi_awvalid <= std_logic(wb_core.cyc and wb_core.we and (not axi_wadr_received));
609-
610-
-- write data channel --
611-
m_axi_wdata <= std_logic_vector(wb_core.do);
612-
m_axi_wstrb <= std_logic_vector(wb_core.sel);
613-
m_axi_wvalid <= std_logic(wb_core.cyc and wb_core.we and (not axi_wdat_received));
614-
615-
-- write response channel --
616-
m_axi_bready <= std_logic(wb_core.cyc and wb_core.we);
617-
618-
619-
-- read/write response --
620-
axi_response: process(wb_core, m_axi_bvalid, m_axi_bresp, m_axi_rvalid, m_axi_rresp)
621-
begin
622-
wb_core.ack <= '0'; -- default
623-
wb_core.err <= '0'; -- default
624-
if (wb_core.we = '1') then -- write operation
625-
if (m_axi_bvalid = '1') then -- valid write response
626-
if (m_axi_bresp = "00") then -- status check
627-
wb_core.ack <= '1'; -- OK
628-
else
629-
wb_core.err <= '1'; -- ERROR
630-
end if;
631-
end if;
632-
else -- read operation
633-
if (m_axi_rvalid = '1') then -- valid read response
634-
if (m_axi_rresp = "00") then -- status check
635-
wb_core.ack <= '1'; -- OK
636-
else
637-
wb_core.err <= '1'; -- ERROR
638-
end if;
639-
end if;
640-
end if;
641-
end process axi_response;
642-
616+
axi4_bridge_inst: xbus2axi4lite_bridge
617+
port map (
618+
-- ------------------------------------------------------------
619+
-- Global Control
620+
-- ------------------------------------------------------------
621+
clk => clk,
622+
resetn => resetn,
623+
-- ------------------------------------------------------------
624+
-- XBUS Device Interface
625+
-- ------------------------------------------------------------
626+
xbus_adr_i => xbus_adr,
627+
xbus_dat_i => xbus_do,
628+
xbus_tag_i => xbus_tag,
629+
xbus_we_i => xbus_we,
630+
xbus_sel_i => xbus_sel,
631+
xbus_stb_i => xbus_stb,
632+
xbus_cyc_i => xbus_cyc,
633+
xbus_ack_o => xbus_ack,
634+
xbus_err_o => xbus_err,
635+
xbus_dat_o => xbus_di,
636+
-- ------------------------------------------------------------
637+
-- AXI4-Lite Host Interface
638+
-- ------------------------------------------------------------
639+
-- Write Address Channel --
640+
m_axi_awaddr => m_axi_awaddr,
641+
m_axi_awprot => m_axi_awprot,
642+
m_axi_awvalid => m_axi_awvalid,
643+
m_axi_awready => m_axi_awready,
644+
-- Write Data Channel --
645+
m_axi_wdata => m_axi_wdata,
646+
m_axi_wstrb => m_axi_wstrb,
647+
m_axi_wvalid => m_axi_wvalid,
648+
m_axi_wready => m_axi_wready,
649+
-- Read Address Channel --
650+
m_axi_araddr => m_axi_araddr,
651+
m_axi_arprot => m_axi_arprot,
652+
m_axi_arvalid => m_axi_arvalid,
653+
m_axi_arready => m_axi_arready,
654+
-- Read Data Channel --
655+
m_axi_rdata => m_axi_rdata,
656+
m_axi_rresp => m_axi_rresp,
657+
m_axi_rvalid => m_axi_rvalid,
658+
m_axi_rready => m_axi_rready,
659+
-- Write Response Channel --
660+
m_axi_bresp => m_axi_bresp,
661+
m_axi_bvalid => m_axi_bvalid,
662+
m_axi_bready => m_axi_bready
663+
);
643664

644665
end architecture neorv32_vivado_ip_rtl;

0 commit comments

Comments
 (0)