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

Add a testbench for the AXI4-lite periph and its deps

parent f6f4fa5d
Branches
Tags
No related merge requests found
----------------------------------------------------------------------------------
-- _ _
-- | |_ ___ _ __(_)__ _
-- | ' \/ -_) '_ \ / _` |
-- |_||_\___| .__/_\__,_|
-- |_|
--
----------------------------------------------------------------------------------
--
-- Company: hepia
-- Author: Laurent Gantel <laurent.gantel@hesge.ch>
--
-- Module Name: sim_axi_rd_pkg - arch
-- Target Device: digilentinc.com:basys3:part0:1.1 xc7a35tcpg236-1
-- Tool version: 2021.1
-- Description: UART package
--
-- Last update: 2022-01-14
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
library sim_axi;
package sim_axi_rd_pkg is
---------------------------------------------------------------------------------
-- Constants
---------------------------------------------------------------------------------
constant SIM_AXI_RD_CLK_PERIOD : time := 10 ns;
---------------------------------------------------------------------------------
-- Types
---------------------------------------------------------------------------------
-- AXI4-Lite Read channels inputs
type axi4lite_rd_bus_in is record
-- Address channel
arready : std_logic;
-- Data channel
rvalid : std_logic;
rdata : std_logic_vector(31 downto 0);
rresp : std_logic_vector(1 downto 0);
end record axi4lite_rd_bus_in;
-- AXI4-Lite Read channels outputs
type axi4lite_rd_bus_out is record
-- Address channel
arvalid : std_logic;
araddr : std_logic_vector(31 downto 0);
-- Data channel
rready : std_logic;
end record axi4lite_rd_bus_out;
---------------------------------------------------------------------------------
-- Functions
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- Procedures
---------------------------------------------------------------------------------
-- Read from AXI4-Lite interface
procedure axi4lite_read (
constant rd_addr : in integer;
signal rd_data : out std_logic_vector(31 downto 0);
-- AXI4-Lite interface
signal s_axi_i : in axi4lite_rd_bus_in;
signal s_axi_o : out axi4lite_rd_bus_out
);
end sim_axi_rd_pkg;
package body sim_axi_rd_pkg is
---------------------------------------------------------------------------------
-- Internal functions
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- Functions
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- Procedures
---------------------------------------------------------------------------------
-- Read from AXI4-Lite interface
procedure axi4lite_read (
constant rd_addr : in integer;
signal rd_data : out std_logic_vector(31 downto 0);
-- AXI4-Lite interface
signal s_axi_i : in axi4lite_rd_bus_in;
signal s_axi_o : out axi4lite_rd_bus_out
) is
begin
-- Set the address
s_axi_o.arvalid <= '1';
s_axi_o.araddr <= std_logic_vector(to_unsigned(rd_addr, 32));
if s_axi_i.arready = '0' then
wait until s_axi_i.arready = '1';
end if;
wait for SIM_AXI_RD_CLK_PERIOD;
s_axi_o.arvalid <= '0';
s_axi_o.araddr <= (others => '0');
-- Get the data
if s_axi_i.rvalid = '0' then
wait until s_axi_i.rvalid = '1';
end if;
wait for SIM_AXI_RD_CLK_PERIOD;
s_axi_o.rready <= '1';
rd_data <= s_axi_i.rdata;
wait for SIM_AXI_RD_CLK_PERIOD;
s_axi_o.rready <= '0';
wait for SIM_AXI_RD_CLK_PERIOD;
end procedure axi4lite_read;
end package body sim_axi_rd_pkg;
----------------------------------------------------------------------------------
-- _ _
-- | |_ ___ _ __(_)__ _
-- | ' \/ -_) '_ \ / _` |
-- |_||_\___| .__/_\__,_|
-- |_|
--
----------------------------------------------------------------------------------
--
-- Company: hepia
-- Author: Laurent Gantel <laurent.gantel@hesge.ch>
--
-- Module Name: sim_axi_wr_pkg - arch
-- Target Device: digilentinc.com:basys3:part0:1.1 xc7a35tcpg236-1
-- Tool version: 2021.1
-- Description: UART package
--
-- Last update: 2022-01-14
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
library sim_axi;
package sim_axi_wr_pkg is
---------------------------------------------------------------------------------
-- Constants
---------------------------------------------------------------------------------
constant SIM_AXI_WR_CLK_PERIOD : time := 10 ns;
---------------------------------------------------------------------------------
-- Types
---------------------------------------------------------------------------------
-- AXI4-Lite Write channels inputs
type axi4lite_wr_bus_in is record
-- Address channel
awready : std_logic;
-- Data channel
wready : std_logic;
-- Response channel
bvalid : std_logic;
bresp : std_logic_vector(1 downto 0);
end record axi4lite_wr_bus_in;
-- AXI4-Lite Write channels outputs
type axi4lite_wr_bus_out is record
-- Address channel
awvalid : std_logic;
awaddr : std_logic_vector(31 downto 0);
-- Data channel
wvalid : std_logic;
wstrb : std_logic_vector(3 downto 0);
wdata : std_logic_vector(31 downto 0);
-- Response channel
bready : std_logic;
end record axi4lite_wr_bus_out;
---------------------------------------------------------------------------------
-- Functions
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- Procedures
---------------------------------------------------------------------------------
-- Write to an AXI4-Lite interface
procedure axi4lite_write (
constant wr_addr : in integer;
constant wr_data : in std_logic_vector(31 downto 0);
-- AXI4-Lite interface
signal s_axi_i : in axi4lite_wr_bus_in;
signal s_axi_o : out axi4lite_wr_bus_out
);
end sim_axi_wr_pkg;
package body sim_axi_wr_pkg is
---------------------------------------------------------------------------------
-- Internal functions
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- Functions
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- Procedures
---------------------------------------------------------------------------------
-- Write to an AXI4-Lite interface
procedure axi4lite_write (
constant wr_addr : in integer;
constant wr_data : in std_logic_vector(31 downto 0);
-- AXI4-Lite interface
signal s_axi_i : in axi4lite_wr_bus_in;
signal s_axi_o : out axi4lite_wr_bus_out
) is
begin
-- Set the address
s_axi_o.awvalid <= '1';
s_axi_o.awaddr <= std_logic_vector(to_unsigned(wr_addr, 32));
-- Set the data
s_axi_o.wvalid <= '1';
s_axi_o.wdata <= wr_data;
s_axi_o.wstrb <= "1111";
wait for SIM_AXI_WR_CLK_PERIOD;
if s_axi_i.awready = '0' then
wait until s_axi_i.awready = '1';
wait for SIM_AXI_WR_CLK_PERIOD;
end if;
s_axi_o.awvalid <= '0';
s_axi_o.awaddr <= (others => '0');
if s_axi_i.wready = '0' then
wait until s_axi_i.wready = '1';
wait for SIM_AXI_WR_CLK_PERIOD;
end if;
s_axi_o.wvalid <= '0';
s_axi_o.wdata <= (others => '0');
s_axi_o.wstrb <= "0000";
-- Validate the transaction
s_axi_o.bready <= '1';
if s_axi_i.bvalid = '0' then
wait until s_axi_i.bvalid = '1';
end if;
wait for SIM_AXI_WR_CLK_PERIOD;
s_axi_o.bready <= '0';
wait for SIM_AXI_WR_CLK_PERIOD;
end procedure axi4lite_write;
end package body sim_axi_wr_pkg;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 03/19/2025 10:06:52 PM
-- Design Name: Test bench for Hog build info AXI4-lite peripheral
-- Module Name: tb_axi4lite_hog_build_info - Behavioral
-- Project Name: Hog build info
-- Target Devices:
-- Tool Versions:
-- Description: Test bench for the Hog build info AXI4-lite peripheral
--
-- Dependencies:
-- - axi4lite_hog_build_info
-- - axi4lite_if
-- - axi4lite_wr_channel_if
-- - axi4lite_rd_channel_if
-- - hog_build_info_regs
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use std.env.finish;
-- Library for simulating AXI4-lite Read and Write
library sim_axi;
use sim_axi.sim_axi_rd_pkg.all;
use sim_axi.sim_axi_wr_pkg.all;
entity tb_axi4lite_hog_build_info is
end tb_axi4lite_hog_build_info;
architecture Behavioral of tb_axi4lite_hog_build_info is
-- External component to test
--- Hog build info AXI4-lite peripheral
component axi4lite_hog_build_info
generic (
C_ADDR_WIDTH: integer := 32 -- Width of the addresses
);
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;
-- Hog build info interface
hog_global_date_i : in std_logic_vector(31 downto 0); -- Hog build global date
hog_global_time_i : in std_logic_vector(31 downto 0); -- Hog build global time
hog_global_ver_i : in std_logic_vector(31 downto 0); -- Hog build global version
hog_global_sha_i : in std_logic_vector(31 downto 0) -- Hog build global latest commit SHA
);
end component axi4lite_hog_build_info;
-- Clock signal and period
constant CLK_PERIOD : time := 10 ns;
signal clk_s : std_logic := '0';
-- Resetn signal
signal resetn_s : std_logic := '1';
-- Config
constant C_ADDR_WIDTH: integer := 32;
-- Registers addresses
constant GDR_BASEADDR : integer := 0; -- Global date register
constant GTR_BASEADDR : integer := 4; -- Global time register
constant GVR_BASEADDR : integer := 8; -- Global version register
constant GSR_BASEADDR : integer := 12; -- Global SHA register
constant UNK_BASEADDR : integer := 14; -- Unknown register
-- Fake Hog build info
constant hog_global_date : std_logic_vector(31 downto 0) := X"13032025";
constant hog_global_time : std_logic_vector(31 downto 0) := X"00123456";
constant hog_global_ver : std_logic_vector(31 downto 0) := X"01020006";
constant hog_global_sha : std_logic_vector(31 downto 0) := X"A98B90F0";
-- Hog build info inputs
signal hog_global_date_s : std_logic_vector(31 downto 0) := (others => '0');
signal hog_global_time_s : std_logic_vector(31 downto 0) := (others => '0');
signal hog_global_ver_s : std_logic_vector(31 downto 0) := (others => '0');
signal hog_global_sha_s : std_logic_vector(31 downto 0) := (others => '0');
-- Data get from the peripheral
signal rd_data_s : std_logic_vector(31 downto 0) := (others => '0');
-- AXI4-lite interface bus
signal axi4lite_rd_bus_i : axi4lite_rd_bus_in := (
-- Address channel
arready => '0',
-- Data channel
rvalid => '0',
rdata => (others => '0'),
rresp => (others => '0')
);
signal axi4lite_rd_bus_o : axi4lite_rd_bus_out := (
-- Address channel
arvalid => '0',
araddr => (others => '0'),
-- Data channel
rready => '0'
);
signal axi4lite_wr_bus_i : axi4lite_wr_bus_in := (
-- Address channel
awready => '0',
-- Data channel
wready => '0',
-- Response channel
bvalid => '0',
bresp => (others => '0')
);
signal axi4lite_wr_bus_o : axi4lite_wr_bus_out := (
-- Address channel
awvalid => '0',
awaddr => (others => '0'),
-- Data channel
wvalid => '0',
wstrb => (others => '0'),
wdata => (others => '0'),
-- Response channel
bready => '0'
);
-- Test bench steps
signal reset_done_s : std_logic := '0';
signal check_reg_0_data_s : std_logic := '0';
signal check_reg_1_data_s : std_logic := '0';
signal check_reg_2_data_s : std_logic := '0';
signal check_reg_3_data_s : std_logic := '0';
signal check_reg_unk_data_s : std_logic := '0';
begin
-- Instance of the peripheral
axi4lite_hog_build_info_inst : axi4lite_hog_build_info
generic map (
C_ADDR_WIDTH => C_ADDR_WIDTH
)
port map (
s_axi_aclk => clk_s,
s_axi_aresetn => resetn_s,
-- AXI4-Lite Write interface
s_axi_awaddr => axi4lite_wr_bus_o.awaddr,
s_axi_awvalid => axi4lite_wr_bus_o.awvalid,
s_axi_awready => axi4lite_wr_bus_i.awready,
s_axi_wdata => axi4lite_wr_bus_o.wdata,
s_axi_wstrb => axi4lite_wr_bus_o.wstrb,
s_axi_wvalid => axi4lite_wr_bus_o.wvalid,
s_axi_wready => axi4lite_wr_bus_i.wready,
s_axi_bresp => axi4lite_wr_bus_i.bresp,
s_axi_bvalid => axi4lite_wr_bus_i.bvalid,
s_axi_bready => axi4lite_wr_bus_o.bready,
-- AXI4-Lite Read interface
s_axi_araddr => axi4lite_rd_bus_o.araddr,
s_axi_arvalid => axi4lite_rd_bus_o.arvalid,
s_axi_arready => axi4lite_rd_bus_i.arready,
s_axi_rdata => axi4lite_rd_bus_i.rdata,
s_axi_rresp => axi4lite_rd_bus_i.rresp,
s_axi_rvalid => axi4lite_rd_bus_i.rvalid,
s_axi_rready => axi4lite_rd_bus_o.rready,
-- Hog build info interface
hog_global_date_i => hog_global_date_s,
hog_global_time_i => hog_global_time_s,
hog_global_ver_i => hog_global_ver_s,
hog_global_sha_i => hog_global_sha_s
);
-- Feed the register bank with fake Hog build info
hog_global_date_s <= hog_global_date;
hog_global_time_s <= hog_global_time;
hog_global_ver_s <= hog_global_ver;
hog_global_sha_s <= hog_global_sha;
-- Clock generator process
clk_process : clk_s <= not clk_s after CLK_PERIOD / 2;
-- Reset process
reset_process: process
begin
resetn_s <= '0';
wait for CLK_PERIOD * 10;
resetn_s <= '1';
wait for CLK_PERIOD;
reset_done_s <= '1';
wait;
end process;
-- Stimulus process
stimulus_process: process
begin
-- Wait until reset is done
wait until reset_done_s = '1';
-- Request to read register 0
axi4lite_read(GDR_BASEADDR, rd_data_s, axi4lite_rd_bus_i, axi4lite_rd_bus_o);
check_reg_0_data_s <= '0';
wait for CLK_PERIOD;
-- Request to read register 1
axi4lite_read(GTR_BASEADDR, rd_data_s, axi4lite_rd_bus_i, axi4lite_rd_bus_o);
check_reg_1_data_s <= '0';
wait for CLK_PERIOD;
-- Request to read register 2
axi4lite_read(GVR_BASEADDR, rd_data_s, axi4lite_rd_bus_i, axi4lite_rd_bus_o);
check_reg_2_data_s <= '0';
wait for CLK_PERIOD;
-- Request to read register 3
axi4lite_read(GSR_BASEADDR, rd_data_s, axi4lite_rd_bus_i, axi4lite_rd_bus_o);
check_reg_3_data_s <= '0';
wait for CLK_PERIOD;
-- Request to read unknown register
axi4lite_read(UNK_BASEADDR, rd_data_s, axi4lite_rd_bus_i, axi4lite_rd_bus_o);
check_reg_unk_data_s <= '0';
wait for CLK_PERIOD;
-- Wait endlessly
wait;
end process stimulus_process;
-- Monitor process
monitor_process: process
begin
-- Check we get register 0 value on data out
wait until check_reg_0_data_s = '1';
wait for CLK_PERIOD;
assert rd_data_s = hog_global_date
report ">>> register 0 value do not correspond to the value feed to the register bank. Instead, get: " & to_hstring(to_bitvector(rd_data_s))
severity failure;
-- Check we get register 1 value on data out
wait until check_reg_1_data_s = '1';
assert rd_data_s = hog_global_time
report ">>> register 1 value do not correspond to the value feed to the register bank. Instead, get: " & to_hstring(to_bitvector(rd_data_s))
severity failure;
-- Check we get register 2 value on data out
wait until check_reg_2_data_s = '1';
assert rd_data_s = hog_global_ver
report ">>> register 1 value do not correspond to the value feed to the register bank. Instead, get: " & to_hstring(to_bitvector(rd_data_s))
severity failure;
-- Check we get register 3 value on data out
wait until check_reg_3_data_s = '1';
assert rd_data_s = hog_global_sha
report ">>> register 1 value do not correspond to the value feed to the register bank. Instead, get: " & to_hstring(to_bitvector(rd_data_s))
severity failure;
-- Check we get 0x0 on data out because of unknown register requested
wait until check_reg_unk_data_s = '1';
assert rd_data_s = X"00000000"
report ">>> rd_data_s is not at 0x0 when unknown register is requested. Instead, get: " & to_hstring(to_bitvector(rd_data_s))
severity failure;
-- If arrive here, the simulation have completed successfully
wait for CLK_PERIOD * 10;
report ">>> Simulation completed successfully";
finish;
end process monitor_process;
end Behavioral;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment