aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/issue2185/avm_master.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/gna/issue2185/avm_master.vhd')
-rw-r--r--testsuite/gna/issue2185/avm_master.vhd198
1 files changed, 198 insertions, 0 deletions
diff --git a/testsuite/gna/issue2185/avm_master.vhd b/testsuite/gna/issue2185/avm_master.vhd
new file mode 100644
index 000000000..b7de25a72
--- /dev/null
+++ b/testsuite/gna/issue2185/avm_master.vhd
@@ -0,0 +1,198 @@
+-- This module is a simple kind of RAM test.
+--
+-- It generates first a sequence of WRITE operations (writing pseudo-random data),
+-- and then a corresponding sequence of READ operations, verifying that the
+-- correct values are read back again.
+--
+-- Created by Michael Jørgensen in 2022 (mjoergen.github.io/HyperRAM).
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity avm_master is
+ generic (
+ G_ADDRESS_SIZE : integer; -- Number of bits
+ G_DATA_SIZE : integer -- Number of bits
+ );
+ port (
+ clk_i : in std_logic;
+ rst_i : in std_logic;
+ start_i : in std_logic;
+ wait_o : out std_logic;
+ write_burstcount_i : in std_logic_vector(7 downto 0);
+ read_burstcount_i : in std_logic_vector(7 downto 0);
+
+ avm_write_o : out std_logic;
+ avm_read_o : out std_logic;
+ avm_address_o : out std_logic_vector(G_ADDRESS_SIZE-1 downto 0);
+ avm_writedata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0);
+ avm_byteenable_o : out std_logic_vector(G_DATA_SIZE/8-1 downto 0);
+ avm_burstcount_o : out std_logic_vector(7 downto 0);
+ avm_readdata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0);
+ avm_readdatavalid_i : in std_logic;
+ avm_waitrequest_i : in std_logic;
+ -- Debug output
+ address_o : out std_logic_vector(G_ADDRESS_SIZE-1 downto 0);
+ data_exp_o : out std_logic_vector(G_DATA_SIZE-1 downto 0);
+ data_read_o : out std_logic_vector(G_DATA_SIZE-1 downto 0);
+ error_o : out std_logic
+ );
+end entity avm_master;
+
+architecture synthesis of avm_master is
+
+ constant C_DATA_INIT : std_logic_vector(63 downto 0) := X"CAFEBABEDEADBEEF";
+
+ signal data_init : std_logic_vector(63 downto 0);
+
+ signal wr_data : std_logic_vector(63 downto 0);
+ signal rd_data : std_logic_vector(63 downto 0);
+ signal burstcount : std_logic_vector(7 downto 0);
+ signal read_burstcount : std_logic_vector(7 downto 0);
+ signal wordcount : integer range 0 to 255;
+ signal new_address : std_logic_vector(G_ADDRESS_SIZE-1 downto 0);
+ signal new_burstcount : std_logic_vector(7 downto 0);
+
+ type state_t is (
+ INIT_ST,
+ WRITING_ST,
+ READING_ST
+ );
+
+ signal state : state_t := INIT_ST;
+ signal reset_verify : std_logic;
+
+ -- The pseudo-random data is generated using a 64-bit maximal-period Galois LFSR,
+ -- see http://users.ece.cmu.edu/~koopman/lfsr/64.txt
+ function lfsr (constant old : std_logic_vector(63 downto 0)) return std_logic_vector is
+ begin
+ if old(63) = '1' then
+ return (old(62 downto 0) & "0") xor x"000000000000001b";
+ else
+ return (old(62 downto 0) & "0");
+ end if;
+ end function lfsr;
+
+begin
+
+ new_address <= avm_address_o when unsigned(avm_burstcount_o) > 1 else
+ std_logic_vector(unsigned(avm_address_o) + wordcount);
+ new_burstcount <= std_logic_vector(unsigned(avm_burstcount_o) - 1) when unsigned(avm_burstcount_o) > 1 else
+ burstcount;
+
+ p_verifier : process (clk_i)
+ begin
+ if rising_edge(clk_i) then
+ if avm_readdatavalid_i = '1' then
+ data_read_o <= avm_readdata_i;
+ data_exp_o <= rd_data(G_DATA_SIZE-1 downto 0);
+
+ if avm_readdata_i /= rd_data(G_DATA_SIZE-1 downto 0) then
+ report "ERROR: Expected " & to_hstring(rd_data(G_DATA_SIZE-1 downto 0)) & ", read " & to_hstring(avm_readdata_i)
+ severity failure;
+ error_o <= '1';
+ else
+ rd_data <= lfsr(rd_data);
+ end if;
+ end if;
+
+ if reset_verify = '1' then
+ rd_data <= data_init;
+ error_o <= '0';
+ end if;
+
+ if rst_i = '1' then
+ error_o <= '0';
+ end if;
+ end if;
+ end process p_verifier;
+
+ p_fsm : process (clk_i)
+ begin
+ if rising_edge(clk_i) then
+ reset_verify <= '0';
+
+ if avm_waitrequest_i = '0' then
+ avm_write_o <= '0';
+ avm_read_o <= '0';
+ end if;
+
+ case state is
+ when INIT_ST =>
+ if start_i = '1' then
+ wait_o <= '1';
+ wr_data <= C_DATA_INIT xor (
+ write_burstcount_i & read_burstcount_i &
+ write_burstcount_i & read_burstcount_i &
+ write_burstcount_i & read_burstcount_i &
+ write_burstcount_i & read_burstcount_i);
+ data_init <= C_DATA_INIT xor (
+ write_burstcount_i & read_burstcount_i &
+ write_burstcount_i & read_burstcount_i &
+ write_burstcount_i & read_burstcount_i &
+ write_burstcount_i & read_burstcount_i);
+ avm_write_o <= '1';
+ avm_read_o <= '0';
+ avm_address_o <= (others => '0');
+ avm_byteenable_o <= (others => '1');
+ avm_burstcount_o <= write_burstcount_i;
+ burstcount <= write_burstcount_i;
+ read_burstcount <= read_burstcount_i;
+ wordcount <= to_integer(unsigned(write_burstcount_i));
+ state <= WRITING_ST;
+ end if;
+
+ when WRITING_ST =>
+ if avm_waitrequest_i = '0' then
+ avm_write_o <= '1';
+ avm_read_o <= '0';
+ avm_address_o <= new_address;
+ avm_byteenable_o <= (others => '1');
+ avm_burstcount_o <= new_burstcount;
+
+ wr_data <= lfsr(wr_data);
+
+ if signed(avm_address_o) = -wordcount and unsigned(avm_burstcount_o) = 1 then
+ wr_data <= data_init;
+ avm_write_o <= '0';
+ avm_address_o <= (others => '0');
+ avm_read_o <= '1';
+ avm_burstcount_o <= read_burstcount;
+ burstcount <= read_burstcount;
+ wordcount <= to_integer(unsigned(read_burstcount));
+ data_read_o <= (others => '0');
+ data_exp_o <= (others => '0');
+ reset_verify <= '1';
+ state <= READING_ST;
+ end if;
+ end if;
+
+ when READING_ST =>
+ if avm_waitrequest_i = '0' then
+
+ if signed(avm_address_o) = -wordcount then
+ wait_o <= '0';
+ state <= INIT_ST;
+ else
+ avm_address_o <= std_logic_vector(unsigned(avm_address_o) + wordcount);
+ avm_read_o <= '1';
+ end if;
+ end if;
+
+ end case;
+
+ if rst_i = '1' then
+ avm_write_o <= '0';
+ avm_read_o <= '0';
+ wait_o <= '0';
+ state <= INIT_ST;
+ end if;
+ end if;
+ end process p_fsm;
+
+ avm_writedata_o <= wr_data(G_DATA_SIZE-1 downto 0);
+ address_o <= avm_address_o;
+
+end architecture synthesis;
+