Commit 902c347a authored by Tristan Gingold's avatar Tristan Gingold

Merge branch 'proposed_master' into 'master'

Merge proposed master into master

See merge request !29
parents b84c76be a0e0f2e5
[submodule "testbench/osvvm/upstream"]
path = testbench/osvvm/upstream
url = https://github.com/OSVVM/OSVVM.git
......@@ -205,6 +205,11 @@ Directory [modules/wishbone](modules/wishbone) contains modules for wishbone.
interface to the digital thermometer.
- [wb_xc7_fw_update](modules/wishbone/wb_xc7_fw_update) is an SPI interface
to drive the xc7 bitstream spi flash (using the ht-flash tool).
- [wb_clock_monitor](modules/wishbone/wb_clock_monitor) is clock frequency
measurement/monitoring core with a programmable number of channels.
- [wb_lm32_mcs](modules/wishbone/wb_lm32_mcs) is a single-entity microcontroller
based on the LM32 softcore, featuring internal code/data RAM, UART, timer and
a pipelined Wishbone peripheral interface.
* There are utilities to handle a wishbone bus:
- [wb_clock_crossing](modules/wishbone/wb_clock_crossing) handle clock domain
......
-------------------------------------------------------------------------------
-- Title : AXI4Full64 to AXI4Lite32 bridge
-- Title : AXI4Lite to AXI4Full bridge
-- Project : General Cores
-------------------------------------------------------------------------------
-- File : axi4lite32_axi4full64_bridge.vhd
-- File : axi4lite_axi4full_bridge.vhd
-- Company : CERN
-- Platform : FPGA-generics
-- Standard : VHDL '93
......@@ -230,8 +230,11 @@ begin
-- Read part.
m_araddr <= raddr;
s_rdata <= rdata;
s_rid <= rid;
s_rdata <= rdata;
s_rid <= rid;
s_rlast <= '1' when (unsigned(rlen)=0 and s_rready = '1' and s_rvalid = '1')
else '0';
process (clk_i)
begin
......@@ -240,7 +243,6 @@ begin
rstate <= RD_IDLE;
s_arready <= '1';
s_rvalid <= '0';
s_rlast <= '0';
m_arvalid <= '0';
m_rready <= '0';
raddr <= (others => 'X');
......@@ -275,6 +277,7 @@ begin
m_arvalid <= '0';
end if;
if m_rvalid = '1' then
m_rready <= '0';
-- Read data. Address must have been acked.
-- According to A3.4.3 of AXI4 spec, the AXI4 bus is little
-- endian.
......@@ -283,11 +286,6 @@ begin
-- To master.
rstate <= RD_SLAVE;
s_rresp <= RSP_OKAY;
if rlen = (g_LEN_WIDTH - 1 downto 0 => '0') then
s_rlast <= '1';
else
s_rlast <= '0';
end if;
s_rvalid <= '1';
end if;
......
......@@ -134,17 +134,17 @@ architecture behav of axi_gpio_expander is
return tmp;
end function;
-------------------------------------------
function f_update_gpio_in (orig : std_logic_vector; rdata : std_logic_vector; bank : integer)
function f_update_gpio_in (orig : std_logic_vector; rd_data : std_logic_vector; bank : integer)
return std_logic_vector is
variable tmp : std_logic_vector(g_num-1 downto 0);
begin
tmp := orig;
if (bank = 0 and g_num >= c_GPIOPS_BANK0) then
tmp(c_GPIOPS_BANK0-1 downto 0) := rdata;
tmp(c_GPIOPS_BANK0-1 downto 0) := rd_data;
elsif (bank = 0 and g_num < c_GPIOPS_BANK0) then
tmp := rdata(g_num-1 downto 0);
tmp := rd_data(g_num-1 downto 0);
else
tmp(g_num-1 downto c_GPIOPS_BANK0) := rdata(g_num-c_GPIOPS_BANK0-1 downto 0);
tmp(g_num-1 downto c_GPIOPS_BANK0) := rd_data(g_num-c_GPIOPS_BANK0-1 downto 0);
end if;
return tmp;
end function;
......@@ -295,7 +295,7 @@ begin
-- write accepted, let's proceed
BREADY <= '0';
state <= INIT_WRITE_OUT;
elsif (BVALID = '1' and BRESP = c_AXI4_RESP_OKAY) then
elsif (BVALID = '1' and BRESP = c_AXI4_RESP_OKAY) then
-- nothing to update in GPIO_OUT, skip to GPIO reading
BREADY <= '0';
state <= INIT_READ;
......@@ -409,7 +409,7 @@ begin
else -- current_bank = 0 and g_num =< c_GPIOPS_BANK0
-- Only Bank0 is used, reset refresh_all flag, Bank0 registers are
-- all set here.
refresh_all <= '0';
refresh_all <= '0';
end if;
state <= IDLE;
......
......@@ -6,7 +6,7 @@
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2011-01-25
-- Last update: 2013-03-04
-- Last update: 2022-07-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -44,7 +44,9 @@ entity generic_dpram is
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_fail_if_file_not_found : boolean := true; -- dummy (exists in Xilinx/generic)
g_dual_clock : boolean := true);
g_dual_clock : boolean := true;
g_implementation_hint : string := "auto"
);
port(
rst_n_i : in std_logic := '1'; -- synchronous reset, active LO
......
......@@ -6,7 +6,7 @@
-- Author : C. Prados
-- Company : GSI
-- Created : 2014-08-25
-- Last update:
-- Last update: 2022-07-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -38,7 +38,9 @@ entity generic_dpram_mixed is
g_size : natural;
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_dual_clock : boolean := true);
g_dual_clock : boolean := true;
g_implementation_hint : string := "auto"
);
port(
rst_n_i : in std_logic := '1'; -- synchronous reset, active LO
......
......@@ -6,7 +6,7 @@
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-03-04
-- Last update: 2013-03-04
-- Last update: 2022-07-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -38,7 +38,8 @@ entity generic_simple_dpram is
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_dual_clock : boolean := true);
g_dual_clock : boolean := true;
g_implementation_hint : string := "auto");
port(
rst_n_i : in std_logic := '1'; -- synchronous reset, active LO
......
......@@ -6,7 +6,7 @@
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2011-01-25
-- Last update: 2013-03-04
-- Last update: 2022-07-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -39,7 +39,8 @@ entity generic_spram is
g_size : natural := 1024;
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "");
g_init_file : string := "";
g_implementation_hint : string := "auto");
port(
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
......
......@@ -53,8 +53,9 @@ entity inferred_async_fifo is
g_with_wr_count : boolean := FALSE;
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer -- threshold for almost full flag
);
g_almost_full_threshold : integer; -- threshold for almost full flag
g_memory_implementation_hint : string := "auto");
port (
rst_n_i : in std_logic := '1';
......@@ -116,11 +117,24 @@ architecture syn of inferred_async_fifo is
bin_x, gray_x : t_counter;
end record;
constant c_counters_reset_value : t_counter_block :=
( bin => (others => '0'),
bin_next => (others => '0'),
gray => (others => '0'),
gray_next => (others => '0'),
bin_x => (others => '0'),
gray_x => (others => '0') );
type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
signal mem : t_mem_type := (others => (others => '0'));
signal rcb, wcb : t_counter_block := (others =>(others => '0'));
attribute ram_type : string;
attribute ram_type of mem : signal is g_memory_implementation_hint;
signal rcb, wcb : t_counter_block := c_counters_reset_value;
signal full_int, empty_int : std_logic;
signal almost_full_int, almost_empty_int : std_logic;
signal going_full : std_logic;
......
......@@ -50,7 +50,8 @@ entity inferred_async_fifo_dual_rst is
g_with_wr_almost_full : boolean := FALSE;
g_with_wr_count : boolean := FALSE;
g_almost_empty_threshold : integer;
g_almost_full_threshold : integer);
g_almost_full_threshold : integer;
g_memory_implementation_hint : string := "auto");
port (
-- write port
rst_wr_n_i : in std_logic := '1';
......@@ -111,6 +112,9 @@ architecture arch of inferred_async_fifo_dual_rst is
signal rcb, wcb : t_counter_block := (others =>(others => '0'));
attribute ram_type : string;
attribute ram_type of mem : signal is g_memory_implementation_hint;
signal full_int, empty_int : std_logic;
signal almost_full_int, almost_empty_int : std_logic;
signal going_full : std_logic;
......
......@@ -54,7 +54,9 @@ entity inferred_sync_fifo is
g_almost_empty_threshold : integer := 0; -- threshold for almost empty flag
g_almost_full_threshold : integer := 0; -- threshold for almost full flag
g_register_flag_outputs : boolean := true
g_register_flag_outputs : boolean := true;
g_memory_implementation_hint : string := "auto"
);
port (
......@@ -105,7 +107,8 @@ begin -- syn
g_size => g_size,
g_with_byte_enable => false,
g_addr_conflict_resolution => "dont_care",
g_dual_clock => false)
g_dual_clock => false,
g_implementation_hint => g_memory_implementation_hint)
port map (
rst_n_i => rst_n_i,
clka_i => clk_i,
......
......@@ -53,7 +53,9 @@ entity generic_async_fifo is
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer -- threshold for almost full flag
g_almost_full_threshold : integer; -- threshold for almost full flag
g_memory_implementation_hint : string := "auto"
);
port (
......@@ -104,7 +106,9 @@ architecture syn of generic_async_fifo is
g_with_wr_almost_full : boolean;
g_with_wr_count : boolean;
g_almost_empty_threshold : integer;
g_almost_full_threshold : integer);
g_almost_full_threshold : integer;
g_memory_implementation_hint : string
);
port (
rst_n_i : in std_logic := '1';
clk_wr_i : in std_logic;
......@@ -144,7 +148,8 @@ begin -- syn
g_with_wr_almost_full => g_with_wr_almost_full,
g_with_wr_count => g_with_wr_count,
g_almost_empty_threshold => g_almost_empty_threshold,
g_almost_full_threshold => g_almost_full_threshold)
g_almost_full_threshold => g_almost_full_threshold,
g_memory_implementation_hint => g_memory_implementation_hint )
port map (
rst_n_i => rst_n_i,
clk_wr_i => clk_wr_i,
......
......@@ -50,7 +50,8 @@ entity generic_async_fifo_dual_rst is
g_with_wr_almost_full : boolean := FALSE;
g_with_wr_count : boolean := FALSE;
g_almost_empty_threshold : integer := 0;
g_almost_full_threshold : integer := 0);
g_almost_full_threshold : integer := 0;
g_memory_implementation_hint : string := "auto" );
port (
-- write port
rst_wr_n_i : in std_logic := '1';
......@@ -96,7 +97,8 @@ begin -- arch
g_with_wr_almost_full => g_with_wr_almost_full,
g_with_wr_count => g_with_wr_count,
g_almost_empty_threshold => g_almost_empty_threshold,
g_almost_full_threshold => g_almost_full_threshold)
g_almost_full_threshold => g_almost_full_threshold,
g_memory_implementation_hint => g_memory_implementation_hint )
port map (
rst_wr_n_i => rst_wr_n_i,
clk_wr_i => clk_wr_i,
......
......@@ -53,7 +53,8 @@ entity generic_sync_fifo is
g_almost_empty_threshold : integer := 0; -- threshold for almost empty flag
g_almost_full_threshold : integer := 0; -- threshold for almost full flag
g_register_flag_outputs : boolean := true
g_register_flag_outputs : boolean := true;
g_memory_implementation_hint : string := "auto"
);
port (
......@@ -90,7 +91,8 @@ architecture syn of generic_sync_fifo is
g_with_count : boolean;
g_almost_empty_threshold : integer;
g_almost_full_threshold : integer;
g_register_flag_outputs : boolean);
g_register_flag_outputs : boolean;
g_memory_implementation_hint : string);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
......@@ -120,8 +122,8 @@ begin -- syn
g_with_count => g_with_count,
g_almost_empty_threshold => g_almost_empty_threshold,
g_almost_full_threshold => g_almost_full_threshold,
g_register_flag_outputs => g_register_flag_outputs)
g_register_flag_outputs => g_register_flag_outputs,
g_memory_implementation_hint => g_memory_implementation_hint )
port map (
rst_n_i => rst_n_i,
clk_i => clk_i,
......
......@@ -48,7 +48,8 @@ package genram_pkg is
g_size : natural;
g_with_byte_enable : boolean := false;
g_init_file : string := "none";
g_addr_conflict_resolution : string := "dont_care") ;
g_addr_conflict_resolution : string := "dont_care";
g_implementation_hint : string := "auto") ;
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
......@@ -66,7 +67,9 @@ package genram_pkg is
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_dual_clock : boolean := true);
g_dual_clock : boolean := true;
g_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clka_i : in std_logic;
......@@ -87,7 +90,9 @@ package genram_pkg is
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_fail_if_file_not_found : boolean := true;
g_dual_clock : boolean := true);
g_dual_clock : boolean := true;
g_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clka_i : in std_logic;
......@@ -111,7 +116,9 @@ package genram_pkg is
g_size : natural;
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_dual_clock : boolean := true);
g_dual_clock : boolean := true;
g_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clka_i : in std_logic;
......@@ -144,7 +151,8 @@ package genram_pkg is
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer := 0;
g_almost_full_threshold : integer := 0);
g_almost_full_threshold : integer := 0;
g_memory_implementation_hint : string := "auto");
port (
rst_wr_n_i : in std_logic := '1';
clk_wr_i : in std_logic;
......@@ -182,7 +190,9 @@ package genram_pkg is
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer := 0;
g_almost_full_threshold : integer := 0);
g_almost_full_threshold : integer := 0;
g_memory_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clk_wr_i : in std_logic;
......@@ -217,7 +227,9 @@ package genram_pkg is
g_with_count : boolean := false;
g_almost_empty_threshold : integer := 0;
g_almost_full_threshold : integer := 0;
g_register_flag_outputs : boolean := true);
g_register_flag_outputs : boolean := true;
g_memory_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
......@@ -248,6 +260,29 @@ package genram_pkg is
q_valid_o : out std_logic
);
end component;
component generic_dpram_split is
generic (
g_size : natural;
g_init_file : string := "none";
g_addr_conflict_resolution : string := "dont_care";
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
bwea_i : in std_logic_vector(3 downto 0);
wea_i : in std_logic;
aa_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
da_i : in std_logic_vector(31 downto 0);
qa_o : out std_logic_vector(31 downto 0);
bweb_i : in std_logic_vector(3 downto 0);
web_i : in std_logic;
ab_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
db_i : in std_logic_vector(31 downto 0);
qb_o : out std_logic_vector(31 downto 0));
end component generic_dpram_split;
end genram_pkg;
......
......@@ -49,7 +49,8 @@ entity generic_dpram is
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_dual_clock : boolean := true;
g_fail_if_file_not_found : boolean := true
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto"
);
port (
......@@ -89,7 +90,9 @@ architecture syn of generic_dpram is
g_size : natural;
g_addr_conflict_resolution : string := "dont_care";
g_init_file : string := "none";
g_fail_if_file_not_found : boolean := true);
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto"
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
......@@ -112,7 +115,9 @@ architecture syn of generic_dpram is
g_with_byte_enable : boolean;
g_addr_conflict_resolution : string;
g_init_file : string;
g_fail_if_file_not_found : boolean);
g_fail_if_file_not_found : boolean;
g_implementation_hint : string
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
......@@ -135,7 +140,9 @@ architecture syn of generic_dpram is
g_with_byte_enable : boolean;
g_addr_conflict_resolution : string;
g_init_file : string;
g_fail_if_file_not_found : boolean);
g_fail_if_file_not_found : boolean;
g_implementation_hint : string
);
port (
rst_n_i : in std_logic := '1';
clka_i : in std_logic;
......@@ -167,7 +174,8 @@ begin
g_size => g_size,
g_addr_conflict_resolution => g_addr_conflict_resolution,
g_init_file => g_init_file,
g_fail_if_file_not_found => g_fail_if_file_not_found)
g_fail_if_file_not_found => g_fail_if_file_not_found,
g_implementation_hint => g_implementation_hint)
port map(
rst_n_i => rst_n_i,
clk_i => clka_i,
......@@ -191,7 +199,8 @@ begin
g_with_byte_enable => g_with_byte_enable,
g_addr_conflict_resolution => g_addr_conflict_resolution,
g_init_file => g_init_file,
g_fail_if_file_not_found => g_fail_if_file_not_found)
g_fail_if_file_not_found => g_fail_if_file_not_found,
g_implementation_hint => g_implementation_hint)
port map (
rst_n_i => rst_n_i,
clk_i => clka_i,
......@@ -217,7 +226,8 @@ begin
g_with_byte_enable => g_with_byte_enable,
g_addr_conflict_resolution => g_addr_conflict_resolution,
g_init_file => g_init_file,
g_fail_if_file_not_found => g_fail_if_file_not_found)
g_fail_if_file_not_found => g_fail_if_file_not_found,
g_implementation_hint => g_implementation_hint)
port map (
rst_n_i => rst_n_i,
clka_i => clka_i,
......
......@@ -48,7 +48,8 @@ entity generic_dpram_dualclock is
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_fail_if_file_not_found : boolean := true
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto"
);
port (
......@@ -122,6 +123,9 @@ architecture syn of generic_dpram_dualclock is
shared variable ram : t_ram_type := f_file_to_ramtype;
attribute ram_type : string;
attribute ram_type of ram : variable is g_implementation_hint;
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0);
signal s_we_b : std_logic_vector(c_num_bytes-1 downto 0);
......
......@@ -47,7 +47,8 @@ entity generic_dpram_sameclock is
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_fail_if_file_not_found : boolean := true
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto"
);
port (
......@@ -122,6 +123,9 @@ architecture syn of generic_dpram_sameclock is
shared variable ram : t_ram_type := f_file_to_ramtype;
attribute ram_type : string;
attribute ram_type of ram : variable is g_implementation_hint;
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0);
signal s_we_b : std_logic_vector(c_num_bytes-1 downto 0);
......
......@@ -61,7 +61,8 @@ entity generic_dpram_split is
g_size : natural := 16384;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_fail_if_file_not_found : boolean := true);
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto");
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
......@@ -112,6 +113,12 @@ architecture syn of generic_dpram_split is
shared variable ram2 : t_split_ram := f_file_to_ramtype(2);
shared variable ram3 : t_split_ram := f_file_to_ramtype(3);
attribute ram_type : string;
attribute ram_type of ram0 : variable is g_implementation_hint;
attribute ram_type of ram1 : variable is g_implementation_hint;
attribute ram_type of ram2 : variable is g_implementation_hint;
attribute ram_type of ram3 : variable is g_implementation_hint;
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0);
signal s_we_b : std_logic_vector(c_num_bytes-1 downto 0);
signal wea_rep : std_logic_vector(c_num_bytes-1 downto 0);
......
......@@ -6,7 +6,7 @@
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-03-04
-- Last update: 2013-10-30
-- Last update: 2022-07-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -58,7 +58,8 @@ entity generic_simple_dpram is
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_dual_clock : boolean := true;
g_fail_if_file_not_found : boolean := true
g_fail_if_file_not_found : boolean := true;
g_implementation_hint : string := "auto"
);
port (
......@@ -93,7 +94,8 @@ begin
g_with_byte_enable => g_with_byte_enable,
g_addr_conflict_resolution => g_addr_conflict_resolution,
g_init_file => g_init_file,
g_dual_clock => g_dual_clock)
g_dual_clock => g_dual_clock,
g_implementation_hint => g_implementation_hint )
port map(
rst_n_i => rst_n_i,
clka_i => clka_i,
......
......@@ -19,7 +19,9 @@ entity generic_spram is
-- RAM read-on-write conflict resolution. Can be "read_first" (read-then-write)
-- or "write_first" (write-then-read)
g_addr_conflict_resolution : string := "write_first";
g_init_file : string := ""
g_init_file : string := "";
g_implementation_hint : string := "auto"
);
port (
......@@ -59,7 +61,10 @@ architecture syn of generic_spram is
signal s_ram_in : std_logic_vector(g_data_width-1 downto 0);
signal s_ram_out : std_logic_vector(g_data_width-1 downto 0);
attribute ram_type : string;
attribute ram_type of ram : signal is g_implementation_hint;
begin
assert (g_init_file = "" or g_init_file = "none")
......
......@@ -31,6 +31,8 @@ modules = { "local" : [
"wbgen2",
"wbgenplus",
"wb_xc7_fw_update",
"wb_lm32_mcs",
"wb_clock_monitor"
]}
files = [
......
files = [
"clock_monitor_wbgen2_pkg.vhd",
"clock_monitor_wb.vhd",
"xwb_clock_monitor.vhd"];
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Clock Frequency Monitor
---------------------------------------------------------------------------------------
-- File : clock_monitor_wb.vhd
-- Author : auto-generated by wbgen2 from clock_monitor_wb.wb
-- Created : Mon Jun 17 18:28:42 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE clock_monitor_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.cm_wbgen2_pkg.all;
entity clock_monitor_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_cm_in_registers;
regs_o : out t_cm_out_registers
);
end clock_monitor_wb;
architecture syn of clock_monitor_wb is
signal cm_cr_cnt_rst_dly0 : std_logic ;
signal cm_cr_cnt_rst_int : std_logic ;
signal cm_cr_presc_int : std_logic_vector(7 downto 0);
signal cm_cr_refsel_int : std_logic_vector(3 downto 0);
signal cm_refdr_refdr_int : std_logic_vector(31 downto 0);
signal cm_cnt_sel_sel_int : std_logic_vector(3 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= slave_i.dat;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
cm_cr_cnt_rst_int <= '0';
cm_cr_presc_int <= "00000000";
cm_cr_refsel_int <= "0000";
cm_refdr_refdr_int <= "00000000000000000000000000000000";
cm_cnt_sel_sel_int <= "0000";
regs_o.cnt_val_valid_load_o <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
cm_cr_cnt_rst_int <= '0';
regs_o.cnt_val_valid_load_o <= '0';
ack_in_progress <= '0';
else
regs_o.cnt_val_valid_load_o <= '0';
end if;
else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (slave_i.we = '1') then
cm_cr_cnt_rst_int <= wrdata_reg(0);
cm_cr_presc_int <= wrdata_reg(8 downto 1);
cm_cr_refsel_int <= wrdata_reg(12 downto 9);
end if;
rddata_reg(0) <= '0';
rddata_reg(8 downto 1) <= cm_cr_presc_int;
rddata_reg(12 downto 9) <= cm_cr_refsel_int;
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "01" =>
if (slave_i.we = '1') then
cm_refdr_refdr_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= cm_refdr_refdr_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (slave_i.we = '1') then
cm_cnt_sel_sel_int <= wrdata_reg(3 downto 0);
end if;
rddata_reg(3 downto 0) <= cm_cnt_sel_sel_int;
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (slave_i.we = '1') then
regs_o.cnt_val_valid_load_o <= '1';
end if;
rddata_reg(30 downto 0) <= regs_i.cnt_val_value_i;
rddata_reg(31) <= regs_i.cnt_val_valid_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
slave_o.dat <= rddata_reg;
-- Reset counters
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
cm_cr_cnt_rst_dly0 <= '0';
regs_o.cr_cnt_rst_o <= '0';
elsif rising_edge(clk_sys_i) then
cm_cr_cnt_rst_dly0 <= cm_cr_cnt_rst_int;
regs_o.cr_cnt_rst_o <= cm_cr_cnt_rst_int and (not cm_cr_cnt_rst_dly0);
end if;
end process;
-- Prescaler
regs_o.cr_presc_o <= cm_cr_presc_int;
-- Reference Select
regs_o.cr_refsel_o <= cm_cr_refsel_int;
-- Reference Division Ratio
regs_o.refdr_refdr_o <= cm_refdr_refdr_int;
-- Counter Select
regs_o.cnt_sel_sel_o <= cm_cnt_sel_sel_int;
-- Counter Value
-- Counter Value Valid/Clear
regs_o.cnt_val_valid_o <= wrdata_reg(31);
rwaddr_reg <= slave_i.adr(3 downto 2);
slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc);
slave_o.err <= '0';
slave_o.rty <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o.ack <= ack_sreg(0);
end syn;
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "Clock Frequency Monitor";
hdl_entity = "clock_monitor_wb";
prefix = "cm";
reg {
name = "Control Register";
prefix = "CR";
field {
name = "Reset counters";
description = "write 1: resets the counters\
write 0: no effect";
prefix = "CNT_RST";
type = MONOSTABLE;
};
field {
name = "Prescaler";
prefix = "PRESC";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Reference Select";
prefix = "REFSEL"; -- 0..n-1: channel n, 14:ext PPS, 15:system clock
type = SLV;
size = 4;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Reference Divider Register";
prefix = "REFDR";
field {
name = "Reference Division Ratio";
prefix = "REFDR";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Counter Select Register";
prefix = "CNT_SEL";
field {
name = "Counter Select";
prefix = "SEL";
type = SLV;
size = 4;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Counter Value Register";
prefix = "CNT_VAL";
field {
name = "Counter Value";
prefix = "VALUE";
type = SLV;
size = 31;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Counter Value Valid/Clear";
prefix = "VALID";
type = BIT;
size = 1;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
};
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Clock Frequency Monitor
---------------------------------------------------------------------------------------
-- File : clock_monitor_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from clock_monitor_wb.wb
-- Created : Mon Jun 17 18:28:42 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE clock_monitor_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package cm_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_cm_in_registers is record
cnt_val_value_i : std_logic_vector(30 downto 0);
cnt_val_valid_i : std_logic;
end record;
constant c_cm_in_registers_init_value: t_cm_in_registers := (
cnt_val_value_i => (others => '0'),
cnt_val_valid_i => '0'
);
-- Output registers (WB slave -> user design)
type t_cm_out_registers is record
cr_cnt_rst_o : std_logic;
cr_presc_o : std_logic_vector(7 downto 0);
cr_refsel_o : std_logic_vector(3 downto 0);
refdr_refdr_o : std_logic_vector(31 downto 0);
cnt_sel_sel_o : std_logic_vector(3 downto 0);
cnt_val_valid_o : std_logic;
cnt_val_valid_load_o : std_logic;
end record;
constant c_cm_out_registers_init_value: t_cm_out_registers := (
cr_cnt_rst_o => '0',
cr_presc_o => (others => '0'),
cr_refsel_o => (others => '0'),
refdr_refdr_o => (others => '0'),
cnt_sel_sel_o => (others => '0'),
cnt_val_valid_o => '0',
cnt_val_valid_load_o => '0'
);
function "or" (left, right: t_cm_in_registers) return t_cm_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component clock_monitor_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_cm_in_registers;
regs_o : out t_cm_out_registers
);
end component;
end package;
package body cm_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_cm_in_registers) return t_cm_in_registers is
variable tmp: t_cm_in_registers;
begin
tmp.cnt_val_value_i := f_x_to_zero(left.cnt_val_value_i) or f_x_to_zero(right.cnt_val_value_i);
tmp.cnt_val_valid_i := f_x_to_zero(left.cnt_val_valid_i) or f_x_to_zero(right.cnt_val_valid_i);
return tmp;
end function;
end package body;
--------------------------------------------------------------------------------
-- CERN BE-CEM-EDL
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: xwb_clock_monitor
--
-- description: Multichannel clock frequency monitor with Wishbone interface.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2020-2021
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.cm_wbgen2_pkg.all;
entity xwb_clock_monitor is
generic (
g_NUM_CLOCKS : integer := 1;
g_CLK_SYS_FREQ : integer := 62500000;
g_WITH_INTERNAL_TIMEBASE : boolean := TRUE
);
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
clk_in_i : in std_logic_vector(g_num_clocks-1 downto 0);
pps_p1_i : in std_logic := '0';
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out
);
end xwb_clock_monitor;
architecture rtl of xwb_clock_monitor is
signal regs_in : t_cm_in_registers;
signal regs_out : t_cm_out_registers;
type t_clock_state is record
presc_cnt : unsigned(4 downto 0);
clk_in : std_logic;
clk_presc : std_logic;
pulse : std_logic;
counter : unsigned(30 downto 0);
valid_sreg : std_logic_vector(1 downto 0);
freq : unsigned(30 downto 0);
ack : std_logic;
end record;
type t_clock_state_array is array (integer range <>) of t_clock_state;
signal clks : t_clock_state_array(0 to g_num_clocks);
signal rst_n_a : std_logic;
signal ref_pulse_p : std_logic;
signal gate_p : std_logic;
signal gate_cnt : unsigned(31 downto 0);
signal pps_p_sysclk : std_logic;
signal cntr_gate : unsigned(30 downto 0) := (others => '0');
signal gate_pulse, gate_pulse_synced : std_logic := '0';
begin
gen_ext_pps : if g_WITH_INTERNAL_TIMEBASE = false generate
U_PPS_Pulse_Detect : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
data_i => pps_p1_i,
ppulse_o => pps_p_sysclk);
end generate gen_ext_pps;
gen_int_pps : if g_WITH_INTERNAL_TIMEBASE = true generate
p_gate_counter : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
cntr_gate <= (others => '0');
pps_p_sysclk <= '0';
else
if cntr_gate = g_CLK_SYS_FREQ-1 then
cntr_gate <= (others => '0');
pps_p_sysclk <= '1';
else
cntr_gate <= cntr_gate + 1;
pps_p_sysclk <= '0';
end if;
end if;
end if;
end process;
end generate gen_int_pps;
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or regs_out.cr_cnt_rst_o = '1' then
gate_cnt <= (others => '0');
gate_p <= '0';
else
ref_pulse_p <= clks(to_integer(unsigned(regs_out.cr_refsel_o))).pulse;
if unsigned(regs_out.cr_refsel_o) /= 15 then
if ref_pulse_p = '1' then
if gate_cnt = unsigned(regs_out.refdr_refdr_o) then
gate_cnt <= (others => '0');
gate_p <= '1';
else
gate_cnt <= gate_cnt + 1;
gate_p <= '0';
end if;
else
gate_p <= '0';
end if;
else
gate_p <= pps_p_sysclk;
end if;
end if;
end if;
end process;
rst_n_a <= rst_n_i;
U_WB_Slave : entity work.clock_monitor_wb
port map (
rst_n_i => rst_n_i,
clk_sys_i => clk_sys_i,
slave_i => slave_i,
slave_o => slave_o,
regs_i => regs_in,
regs_o => regs_out);
clks(g_num_clocks).clk_in <= clk_sys_i;
gen1 : for i in 0 to g_num_clocks-1 generate
clks(i).clk_in <= clk_in_i(i);
end generate gen1;
gen2 : for i in 0 to g_num_clocks generate
p_clk_prescaler : process(clks(i).clk_in, rst_n_a)
begin
if rst_n_a = '0' then
clks(i).presc_cnt <= (others => '0');
clks(i).clk_presc <= '0';
elsif rising_edge(clks(i).clk_in) then
if(clks(i).presc_cnt = unsigned(regs_out.cr_presc_o)) then
clks(i).presc_cnt <= (others => '0');
clks(i).clk_presc <= not clks(i).clk_presc;
else
clks(i).presc_cnt <= clks(i).presc_cnt + 1;
end if;
end if;
end process;
U_Edge_Detect : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
data_i => clks(i).clk_presc,
ppulse_o => clks(i).pulse);
end generate gen2;
gen3 : for i in 0 to g_num_clocks generate
p_counter : process(clk_sys_i)
variable cnt_idx : integer range 0 to g_num_clocks;
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or regs_out.cr_cnt_rst_o = '1' then
clks(i).counter <= (others => '0');
clks(i).valid_sreg <= (others => '0');
else
if(gate_p = '1') then
clks(i).valid_sreg <= clks(i).valid_sreg(0) & '1';
clks(i).freq <= clks(i).counter;
clks(i).counter <= (others => '0');
elsif clks(i).pulse = '1' then
clks(i).counter <= clks(i).counter + 1;
end if;
if clks(i).ack = '1' then
clks(i).valid_sreg(1) <= '0';
end if;
cnt_idx := to_integer(unsigned(regs_out.cnt_sel_sel_o));
if (i = cnt_idx) then
clks(i).ack <= regs_out.cnt_val_valid_o and regs_out.cnt_val_valid_load_o;
else
clks(i).ack <= '0';
end if;
end if;
end if;
end process;
end generate gen3;
p_regs : process(clk_sys_i)
variable cnt_idx : integer range 0 to g_num_clocks;
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
regs_in.cnt_val_valid_i <= '0';
else
cnt_idx := to_integer(unsigned(regs_out.cnt_sel_sel_o));
regs_in.cnt_val_value_i <= std_logic_vector(clks(cnt_idx).freq);
regs_in.cnt_val_valid_i <= clks(cnt_idx).valid_sreg(1);
end if;
end if;
end process;
end rtl;
files = [ "xwb_lm32_mcs.vhd" ];
This diff is collapsed.
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
# This Makefile can be called by the Continuous Integration (CI) tool to execute all
# testbenches added for CI
# AXI4 cores
TB_DIRS+=axi/axi4lite_wb_bridge
TB_DIRS+=axi/z7_axi_gpio_expander
TB_DIRS+=axi/axi4lite32_axi4full64_bridge
TB_DIRS+=axi/axi4lite_axi4full_bridge
.PHONY: $(TB_DIRS)
all: $(TB_DIRS) summary
$(TB_DIRS):
@echo "Run HDLMAKE"
@cd "$@"; \
hdlmake 2>&1
@echo "Run make"
@$(MAKE) -C $@ $(TARGET)
@echo "Run ghdl"
@cd "$@" ;\
./run.sh
@echo "ghdl returned $$?"
summary: $(TB_DIRS)
@echo "-------------------------------------------------------------------"
@echo "Summary:"
@for d in $(TB_DIRS); do \
if [ -f $$d/transcript ]; then \
echo "Warnings for $$d:"; \
cat $$d/transcript | grep Warning; \
if [ $$? -eq 1 ]; then echo "None"; fi ;\
echo "Errors for $$d:"; \
cat $$d/transcript | grep Error; \
if [ $$? -eq 1 ]; then echo "None"; fi ;\
else \
echo "No transcript file for $$d"; \
fi \
done
clean:
@for d in $(TB_DIRS); do \
if [ -f $$d/Makefile ]; then \
$(MAKE) -C $$d $@; \
rm -f $$d/Makefile; \
fi \
done
# Description
The majority of the general cores have their own testbench written in VHDL and as a verification methodology, OSVVM is used. There are also some testbenches which are written in SystemVerilog.
The common features of each test are:
- Randomization of the input signals
- FSM coverage (when there are FSM in the RTL design), results are shown at the end of the simulation
- Assertions are used to verify aspects of the core's functionality, cumply with the specifications
There are two options for the users, in order to run these tests. First is to run them all by using the Makefile in the current directory. This Makefile contains all the VHDL tests. Second option, is to run each test individually.
## Requirements
- [hdlmake](https://hdlmake.readthedocs.io/en/master/#install-hdlmake-package)
- [ghdl](https://ghdl.github.io/ghdl/development/building/index.html#build)
## Set up environment
- OSVVM is a dependency for most of these testbenches. It is already included as a git submodule. Therefore, it is necessary to run at least once `git submodule update --init` before running these testbenches.
## How to test
```console
hdlmake makefile
make
./run.sh
```
Waveform option:
```console
./run.sh --wave=waveform.ghw
```
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
*
!.gitignore
!Manifest.py
!*.vhd
!*.cheby
!run.sh
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
action="simulation"
sim_tool="ghdl"
target="generic"
ghdl_opt="--std=08 -frelaxed-rules -Wno-hide"
sim_top="tb_axi4lite32_axi4full64_bridge"
files="tb_axi4lite32_axi4full64_bridge.vhd"
modules={"local" : ["../../../",
"../../osvvm/",
"../../../modules/wishbone",
"../../../modules/axi"]}
## Description
Testbench for [axi4lite32_axi4full64_bridge](../../modules/axi/axi4lite32_axi4full64_bridge/axi4lite32_axi4full64_bridge.vhd) which is a bridge from AXI4Lite32 to AXI4Full64. Master is the axi4lite and the slave is axi4full.
NOTE: By default, the simulation time is 4ms. For any change in this, run the test and pass the simulation time as an argument to this script:
```console
./run.sh <simulation time>
```
#!/bin/bash -e
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
#This is a simple script to run simulations in GHDL
TB=tb_axi4lite32_axi4full64_bridge
if [ -z "$1" ]; then
TIME="4"
else
TIME="$1"
fi;
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_sim_time=$TIME
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
*
!.gitignore
!Manifest.py
!*.vhd
!*.cheby
!run.sh
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
action ="simulation"
sim_tool="ghdl"
target ="generic"
ghdl_opt="--std=08 -frelaxed-rules -Wno-hide"
sim_top ="tb_axi4lite_axi4full_bridge"
files ="tb_axi4lite_axi4full_bridge.vhd"
modules = {"local" : ["../../../",
"../../osvvm/",
]}
## Description
Testbench for [axi4lite_axi4full_bridge](../../modules/axi/axi4lite_axi4full_bridge/axi4lite_axi4full_bridge.vhd) which is a bridge from AXI4Lite to AXI4Full. Master is the axi4lite and the slave is axi4full.
NOTE: By default, the simulation time is 4ms. For any change in this, run the test and pass the simulation time as an argument (integer) to this script:
```console
./run.sh <simulation time>
```
#!/bin/bash -e
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
#This is a simple script to run simulations in GHDL
TB=tb_axi4lite_axi4full_bridge
if [ -z "$1" ]; then
TIME="4"
else
TIME="$1"
fi;
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_sim_time=$TIME
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
*
!.gitignore
!Manifest.py
!*.vhd
!*.cheby
!run.sh
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
action="simulation"
sim_tool="ghdl"
target="generic"
ghdl_opt="--std=08 -frelaxed-rules -Wno-hide"
sim_top="tb_xaxi4lite_wb_bridge"
files="tb_xaxi4lite_wb_bridge.vhd"
modules={"local" : ["../../../",
"../../osvvm/",
"../../../modules/wishbone",
"../../../modules/axi"]}
## Description
Testbench for [axi4lite_wb_bridge](../../modules/axi/axi4lite_wb_bridge/xaxi4lite_wb_bridge.vhd) which is a bridge from AXI4 Lite to Wishbone. In this core, the Master is AXI4 Lite and Slave is Wishbone.
NOTE: By default, the simulation time is 4ms. To change this, run the test and pass the simulation time as an argument (integer) to this script:
```console
./run.sh <simulation time>
```
#!/bin/bash -e
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
#This is a simple script to run simulations in GHDL
TB=tb_xaxi4lite_wb_bridge
if [ -z "$1" ]; then
TIME="4"
else
TIME="$1"
fi;
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_sim_time=$TIME
This diff is collapsed.
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
*
!.gitignore
!Manifest.py
!*.vhd
!*.cheby
!run.sh
target = "xilinx"
action = "simulation"
sim_tool = "modelsim"
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
target = "xilinx"
action = "simulation"
sim_tool = "ghdl"
top_module = "sim_top_ps_gpio"
syn_device = "XC7Z010"
ghdl_opt = "--std=08 -frelaxed-rules -Wno-hide"
files = [ "gpio_axi.vhd", "sim_top_ps_gpio.vhd" ]
modules = { "local" : ["../../../"] }
modules = { "local" : ["../../../",
"../../osvvm/"] }
-- SPDX-FileCopyrightText: 2023 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
memory-map:
bus: axi4-lite-32
name: axi_gpio
......
-- SPDX-FileCopyrightText: 2023 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
......@@ -78,7 +82,7 @@ begin
wready <= axi_wip and wr_ack_int;
bvalid <= axi_wdone;
process (aclk, areset_n) begin
if areset_n = '0' then
if areset_n = '0' then
axi_wip <= '0';
axi_wdone <= '0';
elsif rising_edge(aclk) then
......@@ -93,7 +97,7 @@ begin
arready <= axi_rip and rd_ack_int;
rvalid <= axi_rdone;
process (aclk, areset_n) begin
if areset_n = '0' then
if areset_n = '0' then
axi_rip <= '0';
axi_rdone <= '0';
rdata <= (others => '0');
......@@ -117,7 +121,7 @@ begin
-- Process for write requests.
process (aclk, areset_n) begin
if areset_n = '0' then
if areset_n = '0' then
wr_ack_int <= '0';
out_b0_reg <= "00000000000000000000000000000000";
out_b1_reg <= "00000000000000000000000000000000";
......@@ -128,41 +132,41 @@ begin
elsif rising_edge(aclk) then
wr_ack_int <= '0';
case awaddr(15 downto 2) is
when "10100000010000" =>
when "10100000010000" =>
-- Register out_b0
if wr_int = '1' then
out_b0_reg <= wdata;
end if;
wr_ack_int <= wr_int;
when "10100000010001" =>
when "10100000010001" =>
-- Register out_b1
if wr_int = '1' then
out_b1_reg <= wdata;
end if;
wr_ack_int <= wr_int;
when "10100000011000" =>
when "10100000011000" =>
-- Register in_b0
when "10100000011001" =>
when "10100000011001" =>
-- Register in_b1
when "10100010000001" =>
when "10100010000001" =>
-- Register dir_b0
if wr_int = '1' then
dir_b0_reg <= wdata;
end if;
wr_ack_int <= wr_int;
when "10100010000010" =>
when "10100010000010" =>
-- Register oen_b0
if wr_int = '1' then
oen_b0_reg <= wdata;
end if;
wr_ack_int <= wr_int;
when "10100010010001" =>
when "10100010010001" =>
-- Register dir_b1
if wr_int = '1' then
dir_b1_reg <= wdata;
end if;
wr_ack_int <= wr_int;
when "10100010010010" =>
when "10100010010010" =>
-- Register oen_b1
if wr_int = '1' then
oen_b1_reg <= wdata;
......@@ -176,36 +180,36 @@ begin
-- Process for registers read.
process (aclk, areset_n) begin
if areset_n = '0' then
if areset_n = '0' then
rd_ack1_int <= '0';
reg_rdat_int <= (others => 'X');
elsif rising_edge(aclk) then
reg_rdat_int <= (others => '0');
case araddr(15 downto 2) is
when "10100000010000" =>
when "10100000010000" =>
-- out_b0
rd_ack1_int <= rd_int;
when "10100000010001" =>
when "10100000010001" =>
-- out_b1
rd_ack1_int <= rd_int;
when "10100000011000" =>
when "10100000011000" =>
-- in_b0
reg_rdat_int <= in_b0_i;
rd_ack1_int <= rd_int;
when "10100000011001" =>
when "10100000011001" =>
-- in_b1
reg_rdat_int <= in_b1_i;
rd_ack1_int <= rd_int;
when "10100010000001" =>
when "10100010000001" =>
-- dir_b0
rd_ack1_int <= rd_int;
when "10100010000010" =>
when "10100010000010" =>
-- oen_b0
rd_ack1_int <= rd_int;
when "10100010010001" =>
when "10100010010001" =>
-- dir_b1
rd_ack1_int <= rd_int;
when "10100010010010" =>
when "10100010010010" =>
-- oen_b1
rd_ack1_int <= rd_int;
when others =>
......@@ -219,35 +223,35 @@ begin
-- By default ack read requests
dato <= (others => '0');
case araddr(15 downto 2) is
when "10100000010000" =>
when "10100000010000" =>
-- out_b0
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100000010001" =>
when "10100000010001" =>
-- out_b1
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100000011000" =>
when "10100000011000" =>
-- in_b0
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100000011001" =>
when "10100000011001" =>
-- in_b1
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100010000001" =>
when "10100010000001" =>
-- dir_b0
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100010000010" =>
when "10100010000010" =>
-- oen_b0
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100010010001" =>
when "10100010010001" =>
-- dir_b1
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10100010010010" =>
when "10100010010010" =>
-- oen_b1
dato <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
......
vsim -t 10fs work.sim_top_ps_gpio -voptargs="+acc"
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
do wave.do
radix -hexadecimal
run 200ms
wave zoomfull
radix -hexadecimal
#!/bin/bash -e
# SPDX-FileCopyrightText: 2023 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0+
#This is a simple script to run simulations in GHDL
TB=sim_top_ps_gpio
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB --stop-time=2ms
echo "********************************************"
-------------------------------------------------------------------------------
-- SPDX-FileCopyrightText: 2023 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
-------------------------------------------------------------------------------
-- Title : AXI PS_GPIO Expander for Zynq-7 Testbench
-- Project : General Cores
-------------------------------------------------------------------------------
......@@ -16,33 +20,35 @@
-- using xsim or GHDL.
--
-------------------------------------------------------------------------------
-- Copyright (c) 2019 CERN
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
--=============================================================================
-- Libraries & Packages --
--=============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
--=============================================================================
-- Entity declaration for sim_top_ps_gpio --
--=============================================================================
entity sim_top_ps_gpio is
end sim_top_ps_gpio;
--==============================================================================
-- Architecture declaration --
--==============================================================================
architecture behav of sim_top_ps_gpio is
-- Constants
constant c_PERIOD : time := 10 ns;
constant c_NUM : integer := 54;
-- Signals
signal clk, rst_n : std_logic;
signal ARVALID : std_logic;
signal AWVALID : std_logic;
signal BREADY : std_logic;
......@@ -105,7 +111,7 @@ begin
ARADDR => ARADDR,
AWADDR => AWADDR,
WDATA => WDATA,
WSTRB => WSTRB,
WSTRB => WSTRB,
ARREADY => ARREADY,
AWREADY => AWREADY,
BVALID => BVALID,
......@@ -128,7 +134,7 @@ begin
araddr => ARADDR(15 downto 2),
awaddr => AWADDR(15 downto 2),
wdata => WDATA,
wstrb => WSTRB,
wstrb => WSTRB,
arready => ARREADY,
awready => AWREADY,
bvalid => BVALID,
......@@ -194,4 +200,34 @@ begin
wait;
end process;
--==============================================================================
-- Assertions --
--==============================================================================
-- Check AXI-4 LITE signals
p_axi_check : process(AWREADY,WREADY,BVALID,ARREADY,RVALID)
begin
if falling_edge(AWREADY) then
assert (AWVALID = '0')
report "Wrong AWVALID for AWREADY LOW" severity failure;
end if;
if falling_edge(WREADY) then
assert (WVALID = '0')
report "Wrong WVALID for WREADY LOW" severity failure;
end if;
if falling_edge(BVALID) then
assert (BREADY = '0')
report "Wrong BREADY for BVALID LOW" severity failure;
end if;
if falling_edge(ARREADY) then
assert (ARVALID = '0')
report "Wrong ARVALID for ARREADY LOW" severity failure;
end if;
if falling_edge(RVALID) then
assert (RREADY = '0')
report "Wrong RREADY for RVALID LOW" severity failure;
end if;
end process;
end behav;
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /sim_top_ps_gpio/clk
add wave -noupdate /sim_top_ps_gpio/rst_n
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/ARVALID
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/AWVALID
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/BREADY
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/RREADY
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/WVALID
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/ARADDR
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/AWADDR
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/WDATA
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/WSTRB
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/ARREADY
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/AWREADY
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/BVALID
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/RVALID
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/WREADY
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/BRESP
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/RRESP
add wave -noupdate -expand -group AXI /sim_top_ps_gpio/RDATA
add wave -noupdate /sim_top_ps_gpio/error_b1
add wave -noupdate /sim_top_ps_gpio/out_b0
add wave -noupdate /sim_top_ps_gpio/out_b1
add wave -noupdate /sim_top_ps_gpio/dir_b0
add wave -noupdate /sim_top_ps_gpio/dir_b1
add wave -noupdate /sim_top_ps_gpio/oen_b0
add wave -noupdate /sim_top_ps_gpio/oen_b1
add wave -noupdate /sim_top_ps_gpio/gpio_out
add wave -noupdate /sim_top_ps_gpio/gpio_oe
add wave -noupdate /sim_top_ps_gpio/gpio_dir
add wave -noupdate /sim_top_ps_gpio/gpio_in
add wave -noupdate /sim_top_ps_gpio/U_EXP/state
add wave -noupdate /sim_top_ps_gpio/U_EXP/gpio_oe_prev
add wave -noupdate /sim_top_ps_gpio/U_EXP/gpio_dir_prev
add wave -noupdate /sim_top_ps_gpio/U_EXP/gpio_out_prev
add wave -noupdate /sim_top_ps_gpio/U_EXP/gpio_oe_changed
add wave -noupdate /sim_top_ps_gpio/U_EXP/gpio_dir_changed
add wave -noupdate /sim_top_ps_gpio/U_EXP/gpio_out_changed
add wave -noupdate /sim_top_ps_gpio/U_EXP/refresh_all
add wave -noupdate /sim_top_ps_gpio/U_EXP/current_bank
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {0 fs} 0}
quietly wave cursor active 0
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits fs
update
WaveRestoreZoom {0 fs} {5780 fs}
library="osvvm"
files = [
"upstream/AlertLogPkg.vhd",
"upstream/CoveragePkg.vhd",
"upstream/MemoryGenericPkg.vhd",
"upstream/MemoryPkg.vhd",
"upstream/MemorySupportPkg.vhd",
"upstream/MessageListPkg.vhd",
"upstream/MessagePkg.vhd",
"upstream/NamePkg.vhd",
"upstream/NameStorePkg.vhd",
"upstream/OsvvmContext.vhd",
"upstream/OsvvmGlobalPkg.vhd",
"upstream/OsvvmTypesPkg.vhd",
"upstream/RandomBasePkg.vhd",
"upstream/RandomPkg.vhd",
"upstream/RandomProcedurePkg.vhd",
"upstream/ReportPkg.vhd",
"upstream/ResizePkg.vhd",
"upstream/ResolutionPkg.vhd",
"upstream/ScoreboardGenericPkg.vhd",
"upstream/ScoreboardPkg_int.vhd",
"upstream/ScoreboardPkg_slv.vhd",
"upstream/SortListPkg_int.vhd",
"upstream/TbUtilPkg.vhd",
"upstream/TextUtilPkg.vhd",
"upstream/TranscriptPkg.vhd",
"upstream/VendorCovApiPkg.vhd",
]
Subproject commit 0bced0107438a612b8656d5ae80a6d1a32f22b81
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment