Skip to content
Snippets Groups Projects
Commit 597dd8c4 authored by sebastie.gendre's avatar sebastie.gendre
Browse files

Add AXI4lite interface entities

parent b2a67b8e
Branches
Tags
No related merge requests found
hog-build-info/hog-build-info.srcs/sources_1/new/hog_build_info_regs.vhd top=hog_build_info_regs 93
hog-build-info/hog-build-info.srcs/sources_1/new/axi4lite_rd_channel_if.vhd 93
hog-build-info/hog-build-info.srcs/sources_1/new/axi4lite_wr_channel_if.vhd 93
hog-build-info/hog-build-info.srcs/sources_1/new/axi4lite_if.vhd 93
----------------------------------------------------------------------------------
-- _ _
-- | |_ ___ _ __(_)__ _
-- | ' \/ -_) '_ \ / _` |
-- |_||_\___| .__/_\__,_|
-- |_|
--
----------------------------------------------------------------------------------
--
-- Company: Hepia // HES-SO
-- Author: Laurent Gantel <laurent.gantel@hesge.ch>
--
-- Module Name: axi4lite_if - arch
-- Target Device: digilentinc.com:basys3:part0:1.1 xc7a35tcpg236-1
-- Tool version: 2021.1
-- Description: axi4lite_if
--
-- Last update: 2024-12-15
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axi4lite_if is
generic (
C_DATA_WIDTH : integer := 32;
C_ADDR_WIDTH : integer := 4
);
port (
s_axi_aclk : in std_logic;
s_axi_aresetn : in std_logic;
-- AXI4-Lite Write interface
s_axi_awaddr : in std_logic_vector(31 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;
-- AXI4-Lite Read interface
s_axi_araddr : in std_logic_vector(31 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;
-- Write register interface
wr_valid_o : out std_logic;
wr_addr_o : out std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
wr_data_o : out std_logic_vector((C_DATA_WIDTH - 1) downto 0);
-- Read register interface
rd_valid_o : out std_logic;
rd_addr_o : out std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
rd_data_i : in std_logic_vector((C_DATA_WIDTH - 1) downto 0)
);
end axi4lite_if;
architecture arch of axi4lite_if is
---------------------------------------------------------------------------------
-- Write interface
---------------------------------------------------------------------------------
component axi4lite_wr_channel_if is
generic (
C_DATA_WIDTH : integer;
C_ADDR_WIDTH : integer
);
port (
s_axi_aclk : in std_logic;
s_axi_aresetn : in std_logic;
s_axi_awaddr : in std_logic_vector(31 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;
valid_o : out std_logic;
addr_o : out std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
data_o : out std_logic_vector((C_DATA_WIDTH - 1) downto 0)
);
end component axi4lite_wr_channel_if;
signal wr_if_s_axi_aclk : std_logic;
signal wr_if_s_axi_aresetn : std_logic;
signal wr_if_s_axi_awaddr : std_logic_vector(31 downto 0);
signal wr_if_s_axi_awvalid : std_logic;
signal wr_if_s_axi_awready : std_logic;
signal wr_if_s_axi_wdata : std_logic_vector(31 downto 0);
signal wr_if_s_axi_wstrb : std_logic_vector(3 downto 0);
signal wr_if_s_axi_wvalid : std_logic;
signal wr_if_s_axi_wready : std_logic;
signal wr_if_s_axi_bresp : std_logic_vector(1 downto 0);
signal wr_if_s_axi_bvalid : std_logic;
signal wr_if_s_axi_bready : std_logic;
signal wr_if_valid_o : std_logic;
signal wr_if_addr_o : std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
signal wr_if_data_o : std_logic_vector((C_DATA_WIDTH - 1) downto 0);
---------------------------------------------------------------------------------
-- Read interface
---------------------------------------------------------------------------------
component axi4lite_rd_channel_if is
generic (
C_DATA_WIDTH : integer;
C_ADDR_WIDTH : integer
);
port (
s_axi_aclk : in std_logic;
s_axi_aresetn : in std_logic;
s_axi_araddr : in std_logic_vector(31 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;
valid_o : out std_logic;
addr_o : out std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
data_i : in std_logic_vector((C_DATA_WIDTH - 1) downto 0)
);
end component axi4lite_rd_channel_if;
signal rd_if_s_axi_aclk : std_logic;
signal rd_if_s_axi_aresetn : std_logic;
signal rd_if_s_axi_araddr : std_logic_vector(31 downto 0);
signal rd_if_s_axi_arvalid : std_logic;
signal rd_if_s_axi_arready : std_logic;
signal rd_if_s_axi_rdata : std_logic_vector(31 downto 0);
signal rd_if_s_axi_rresp : std_logic_vector(1 downto 0);
signal rd_if_s_axi_rvalid : std_logic;
signal rd_if_s_axi_rready : std_logic;
signal rd_if_valid_o : std_logic;
signal rd_if_addr_o : std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
signal rd_if_data_i : std_logic_vector((C_DATA_WIDTH - 1) downto 0);
begin
---------------------------------------------------------------------------------
-- Write interface
---------------------------------------------------------------------------------
axi4lite_wr_channel_if_i : entity work.axi4lite_wr_channel_if
generic map (
C_DATA_WIDTH => C_DATA_WIDTH,
C_ADDR_WIDTH => C_ADDR_WIDTH
)
port map (
s_axi_aclk => wr_if_s_axi_aclk,
s_axi_aresetn => wr_if_s_axi_aresetn,
s_axi_awaddr => wr_if_s_axi_awaddr,
s_axi_awvalid => wr_if_s_axi_awvalid,
s_axi_awready => wr_if_s_axi_awready,
s_axi_wdata => wr_if_s_axi_wdata,
s_axi_wstrb => wr_if_s_axi_wstrb,
s_axi_wvalid => wr_if_s_axi_wvalid,
s_axi_wready => wr_if_s_axi_wready,
s_axi_bresp => wr_if_s_axi_bresp,
s_axi_bvalid => wr_if_s_axi_bvalid,
s_axi_bready => wr_if_s_axi_bready,
valid_o => wr_if_valid_o,
addr_o => wr_if_addr_o,
data_o => wr_if_data_o
);
wr_if_s_axi_aclk <= s_axi_aclk;
wr_if_s_axi_aresetn <= s_axi_aresetn;
--
wr_if_s_axi_awaddr <= s_axi_awaddr;
wr_if_s_axi_awvalid <= s_axi_awvalid;
s_axi_awready <= wr_if_s_axi_awready;
wr_if_s_axi_wdata <= s_axi_wdata;
wr_if_s_axi_wstrb <= s_axi_wstrb;
wr_if_s_axi_wvalid <= s_axi_wvalid;
s_axi_wready <= wr_if_s_axi_wready;
s_axi_bresp <= wr_if_s_axi_bresp;
s_axi_bvalid <= wr_if_s_axi_bvalid;
wr_if_s_axi_bready <= s_axi_bready;
--
wr_valid_o <= wr_if_valid_o;
wr_addr_o <= wr_if_addr_o;
wr_data_o <= wr_if_data_o;
---------------------------------------------------------------------------------
-- Read interface
---------------------------------------------------------------------------------
axi4lite_rd_channel_if_i : entity work.axi4lite_rd_channel_if
generic map (
C_DATA_WIDTH => C_DATA_WIDTH,
C_ADDR_WIDTH => C_ADDR_WIDTH
)
port map (
s_axi_aclk => rd_if_s_axi_aclk,
s_axi_aresetn => rd_if_s_axi_aresetn,
s_axi_araddr => rd_if_s_axi_araddr,
s_axi_arvalid => rd_if_s_axi_arvalid,
s_axi_arready => rd_if_s_axi_arready,
s_axi_rdata => rd_if_s_axi_rdata,
s_axi_rresp => rd_if_s_axi_rresp,
s_axi_rvalid => rd_if_s_axi_rvalid,
s_axi_rready => rd_if_s_axi_rready,
valid_o => rd_if_valid_o,
addr_o => rd_if_addr_o,
data_i => rd_if_data_i
);
rd_if_s_axi_aclk <= s_axi_aclk;
rd_if_s_axi_aresetn <= s_axi_aresetn;
--
rd_if_s_axi_araddr <= s_axi_araddr;
rd_if_s_axi_arvalid <= s_axi_arvalid;
s_axi_arready <= rd_if_s_axi_arready;
s_axi_rdata <= rd_if_s_axi_rdata;
s_axi_rresp <= rd_if_s_axi_rresp;
s_axi_rvalid <= rd_if_s_axi_rvalid;
rd_if_s_axi_rready <= s_axi_rready;
--
rd_valid_o <= rd_if_valid_o;
rd_addr_o <= rd_if_addr_o;
rd_if_data_i <= rd_data_i;
end arch;
----------------------------------------------------------------------------------
-- Company: hepia // HES-SO
-- Engineer: Laurent Gantel <laurent.gantel@hesge.ch>
--
-- Module Name: axi4lite_rd_channel_if - arch
-- Target Devices: Xilinx Artix7 xc7a100tcsg324-1
-- Tool versions: 2014.2
-- Description: AXI4-Lite Read Channel interface
--
-- Last update: 2022-01-09
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity axi4lite_rd_channel_if is
generic (
C_DATA_WIDTH : integer := 32;
C_ADDR_WIDTH : integer := 10
);
port (
s_axi_aclk : in std_logic;
s_axi_aresetn : in std_logic;
-- Read channel
s_axi_araddr : in std_logic_vector(31 downto 0); -- Read address
s_axi_arvalid : in std_logic; -- Read address validation
s_axi_arready : out std_logic; -- Ready to receive a valid address
s_axi_rdata : out std_logic_vector(31 downto 0); -- Read data
s_axi_rresp : out std_logic_vector(1 downto 0); -- Read response status (not specified)
s_axi_rvalid : out std_logic; -- Indicate that valid data can be read
s_axi_rready : in std_logic; -- Indicate that the master can accept a read data and response information
-- Data interface
valid_o : out std_logic;
addr_o : out std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
data_i : in std_logic_vector((C_DATA_WIDTH - 1) downto 0)
);
end entity axi4lite_rd_channel_if;
architecture arch of axi4lite_rd_channel_if is
-- AXI4-Lite signals
signal s_axi_arready_s : std_logic := '0';
signal s_axi_rvalid_s : std_logic := '0';
signal s_axi_rresp_s : std_logic_vector(1 downto 0) := (others => '0');
-- Intermediate signals
signal rd_addr_latched : std_logic := '0';
signal addr_s : std_logic_vector((C_ADDR_WIDTH - 1) downto 0) := (others => '0');
signal data_s : std_logic_vector((C_DATA_WIDTH - 1) downto 0) := (others => '0');
begin
--
-- Read channel: Generate the arready signal - Latch the address
--
-- The arready signal is deasserted at reset and when the arvalid signal is set.
-- It is reasserted once rready is asserted by the master.
--
process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
-- Deassert at reset
if s_axi_aresetn = '0' then
s_axi_arready_s <= '0';
rd_addr_latched <= '0';
-- Deassert when arvalid is asserted
elsif s_axi_arvalid = '1' then
s_axi_arready_s <= '0';
rd_addr_latched <= '1';
-- Reassert it when rready is asserted
elsif s_axi_rready = '1' and s_axi_arready_s = '0' then
s_axi_arready_s <= '1';
rd_addr_latched <= '0';
-- When the address has been latched, keep it LOW until rready is asserted
elsif rd_addr_latched = '1' then
s_axi_arready_s <= '0';
-- By default, arready is HIGH
else
s_axi_arready_s <= '1';
rd_addr_latched <= rd_addr_latched;
end if;
end if;
end process;
s_axi_arready <= s_axi_arready_s;
-- Latch the read channel address
addr_o <= s_axi_araddr((C_ADDR_WIDTH - 1) downto 0) when s_axi_arvalid = '1' and s_axi_arready_s = '1' else
addr_s;
valid_o <= s_axi_arvalid and s_axi_arready_s;
process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
if s_axi_aresetn = '0' then
addr_s <= (others => '0');
elsif s_axi_arvalid = '1' and s_axi_arready_s = '1' then
addr_s <= s_axi_araddr((C_ADDR_WIDTH - 1) downto 0);
else
addr_s <= addr_s;
end if;
end if;
end process;
--
-- Read channel: Generate the rvalid signal - Latch the data
--
-- The rvalid signal is asserted once a valid address has been set
-- on the araddr port.
--
-- FIXME: The rresp signal is always "00" to indicate a valid transation.
--
-- Generate the rvalid signal
process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
if s_axi_aresetn = '0' then
s_axi_rvalid_s <= '0';
s_axi_rresp_s <= "00";
-- Assert rvalid once a valid address has been set on the araddr port
elsif s_axi_arvalid = '1' and s_axi_arready_s = '1' then
s_axi_rvalid_s <= '1';
s_axi_rresp_s <= "00";
-- Deassert rvalid when the read data has been acknowledged
elsif s_axi_rready = '1' and s_axi_rvalid_s = '1' then
s_axi_rvalid_s <= '0';
s_axi_rresp_s <= "00";
else
s_axi_rvalid_s <= s_axi_rvalid_s;
s_axi_rresp_s <= s_axi_rresp_s;
end if;
end if;
end process;
s_axi_rvalid <= s_axi_rvalid_s;
s_axi_rresp <= s_axi_rresp_s;
s_axi_rdata <= data_i;
end arch;
----------------------------------------------------------------------------------
-- Company: hepia // HES-SO
-- Engineer: Laurent Gantel <laurent.gantel@hesge.ch>
--
-- Module Name: axi4lite_wr_channel_if - arch
-- Target Devices: Xilinx Artix7 xc7a100tcsg324-1
-- Tool versions: 2014.2
-- Description: AXI4-Lite Write Channel interface
--
-- Last update: 2022-01-09
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity axi4lite_wr_channel_if is
generic (
C_DATA_WIDTH : integer := 32;
C_ADDR_WIDTH : integer := 10
);
port (
s_axi_aclk : in std_logic;
s_axi_aresetn : in std_logic;
---------------------------------------------------------------------------------
-- Write interface
---------------------------------------------------------------------------------
-- Write Address channel
s_axi_awaddr : in std_logic_vector(31 downto 0); -- Write address
s_axi_awvalid : in std_logic; -- Write address validation
s_axi_awready : out std_logic; -- Ready to receive a valid address
-- Write Data channel
s_axi_wdata : in std_logic_vector(31 downto 0); -- Data to be written
s_axi_wstrb : in std_logic_vector(3 downto 0); -- Write data byte enable
s_axi_wvalid : in std_logic; -- Write data validation
s_axi_wready : out std_logic; -- Ready to receive data
-- Write Response channel
s_axi_bresp : out std_logic_vector(1 downto 0); -- Write response status (not specified)
s_axi_bvalid : out std_logic; -- Write response validation
s_axi_bready : in std_logic; -- Indicate that the master can accept a write response
-- Data interface
valid_o : out std_logic;
addr_o : out std_logic_vector((C_ADDR_WIDTH - 1) downto 0);
data_o : out std_logic_vector((C_DATA_WIDTH - 1) downto 0)
);
end entity axi4lite_wr_channel_if;
architecture arch of axi4lite_wr_channel_if is
-- AXI4-Lite signals
signal s_axi_awready_s : std_logic := '0';
signal s_axi_wready_s : std_logic := '0';
signal s_axi_bvalid_s : std_logic := '0';
signal s_axi_bresp_s : std_logic_vector(1 downto 0) := (others => '0');
-- Intermediate signals
signal aw_en : std_logic := '0';
signal valid_s : std_logic := '0';
signal addr_s : std_logic_vector((C_ADDR_WIDTH - 1) downto 0) := (others => '0');
signal data_s : std_logic_vector((C_DATA_WIDTH - 1) downto 0) := (others => '0');
begin
---------------------------------------------------------------------------------
-- Write address channel:
---------------------------------------------------------------------------------
-- Generate the awready signal
--
awready_gen_proc : process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
-- Deassert at reset
if s_axi_aresetn = '0' then
s_axi_awready_s <= '0';
aw_en <= '1';
else
s_axi_awready_s <= '0';
aw_en <= aw_en;
-- Assert awready when the slave is ready to accept an address AND when there is
-- a valid write address AND write data on the address and data bus.
if s_axi_awvalid = '1' and s_axi_wvalid = '1' and aw_en = '1' then -- and s_axi_awready_s = '0' ??
s_axi_awready_s <= '1';
aw_en <= '0';
-- Deassert awready when a write response has been given
elsif s_axi_bready = '1' and s_axi_bvalid_s = '1' then
aw_en <= '1';
end if;
end if;
end if;
end process awready_gen_proc;
s_axi_awready <= s_axi_awready_s;
-- Latch the write channel address
--
latch_awaddr_proc : process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
if s_axi_aresetn = '0' then
addr_s <= (others => '0');
else
if s_axi_awvalid = '1' and s_axi_wvalid = '1' and aw_en = '1' then -- and s_axi_awready_s = '0' ??
addr_s <= s_axi_awaddr((C_ADDR_WIDTH - 1) downto 0);
else
addr_s <= addr_s;
end if;
end if;
end if;
end process latch_awaddr_proc;
addr_o <= addr_s;
---------------------------------------------------------------------------------
-- Write Data channel:
---------------------------------------------------------------------------------
-- Generate the wready signal
--
-- The wready signal is asserted once both awvalid and awready signals have been asserted
-- due to a valid address on the awaddr port.
--
-- Generate the wready signal
wready_gen_proc : process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
if s_axi_aresetn = '0' then
s_axi_wready_s <= '0';
else
-- Slave is ready to accept write data when there is a valid write address and write data
-- on the write address and data bus.
-- Keep the signal high for one cycle
if s_axi_wready_s = '0' and s_axi_awvalid = '1' and s_axi_wvalid = '1' and aw_en = '1' then
s_axi_wready_s <= '1';
else
s_axi_wready_s <= '0';
end if;
end if;
end if;
end process wready_gen_proc;
s_axi_wready <= s_axi_wready_s;
-- Latch and Write the data
--
latch_wdata_proc : process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
if s_axi_aresetn = '0' then
valid_s <= '0';
data_s <= (others => '0');
else
-- Slave register write enable is asserted when valid address and data are available
-- and the slave is ready to accept the write address and write data.
if s_axi_wvalid = '1' and s_axi_wready_s = '1' then
valid_s <= '1';
data_s <= s_axi_wdata((C_DATA_WIDTH - 1) downto 0);
else
valid_s <= '0';
data_s <= (others => '0');
end if;
end if;
end if;
end process latch_wdata_proc;
valid_o <= valid_s;
data_o <= data_s;
--
-- Write Response channel: Generate the bvalid signal and the bresp signal
--
-- The write response and response valid signals are asserted by the slave
-- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
-- This marks the acceptance of address and indicates the status of
-- write transaction.
--
response_proc : process(s_axi_aclk)
begin
if rising_edge(s_axi_aclk) then
if s_axi_aresetn = '0' then
s_axi_bvalid_s <= '0';
s_axi_bresp_s <= (others => '0');
else
if s_axi_wvalid = '1' and s_axi_wready_s = '1' then
s_axi_bvalid_s <= '1';
s_axi_bresp_s <= (others => '0');
elsif (s_axi_bready = '1' and s_axi_bvalid_s = '1') then --check if bready is asserted while bvalid is high)
s_axi_bvalid_s <= '0'; -- (there is a possibility that bready is always asserted high)
else
s_axi_bvalid_s <= s_axi_bvalid_s;
s_axi_bresp_s <= s_axi_bresp_s;
end if;
end if;
end if;
end process response_proc;
s_axi_bvalid <= s_axi_bvalid_s;
s_axi_bresp <= s_axi_bresp_s;
end arch;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment