countzero: Add a testbench
authorPaul Mackerras <paulus@ozlabs.org>
Thu, 10 Oct 2019 04:09:41 +0000 (15:09 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Sun, 13 Oct 2019 21:43:38 +0000 (08:43 +1100)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Makefile
countzero_tb.vhdl [new file with mode: 0644]

index 26945566a40eeefa62e061226535e55f6e5877e6..43f1634198c4f7e7044bb022c794fc8773665046 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ GHDLFLAGS=--std=08 -Psim-unisim
 CFLAGS=-O2 -Wall
 
 all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb multiply_tb dmi_dtm_tb divider_tb \
-       rotator_tb
+       rotator_tb countzero_tb
 
 # XXX
 # loadstore_tb fetch_tb
@@ -19,6 +19,7 @@ core_tb.o: common.o wishbone_types.o core.o soc.o sim_jtag.o
 core.o: common.o wishbone_types.o fetch1.o fetch2.o icache.o decode1.o decode2.o register_file.o cr_file.o execute1.o execute2.o loadstore1.o loadstore2.o multiply.o writeback.o core_debug.o divider.o
 core_debug.o: common.o
 countzero.o:
+countzero_tb.o: common.o glibc_random.o countzero.o
 cr_file.o: common.o
 crhelpers.o: common.o
 decode1.o: common.o decode_types.o
@@ -95,6 +96,9 @@ divider_tb: divider_tb.o
 rotator_tb: rotator_tb.o
        $(GHDL) -e $(GHDLFLAGS) $@
 
+countzero_tb: countzero_tb.o
+       $(GHDL) -e $(GHDLFLAGS) $@
+
 simple_ram_tb: simple_ram_tb.o
        $(GHDL) -e $(GHDLFLAGS) $@
 
diff --git a/countzero_tb.vhdl b/countzero_tb.vhdl
new file mode 100644 (file)
index 0000000..91de334
--- /dev/null
@@ -0,0 +1,105 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.common.all;
+use work.glibc_random.all;
+
+entity countzero_tb is
+end countzero_tb;
+
+architecture behave of countzero_tb is
+    constant clk_period: time := 10 ns;
+    signal rs: std_ulogic_vector(63 downto 0);
+    signal is_32bit, count_right: std_ulogic := '0';
+    signal result: std_ulogic_vector(63 downto 0);
+    signal randno: std_ulogic_vector(63 downto 0);
+
+begin
+    zerocounter_0: entity work.zero_counter
+       port map (
+           rs => rs,
+           result => result,
+           count_right => count_right,
+           is_32bit => is_32bit
+       );
+
+    stim_process: process
+        variable r: std_ulogic_vector(63 downto 0);
+    begin
+        -- test with input = 0
+        report "test zero input";
+        rs <= (others => '0');
+        is_32bit <= '0';
+        count_right <= '0';
+        wait for clk_period;
+        assert result = x"0000000000000040"
+            report "bad cntlzd 0 = " & to_hstring(result);
+        count_right <= '1';
+        wait for clk_period;
+        assert result = x"0000000000000040"
+            report "bad cnttzd 0 = " & to_hstring(result);
+        is_32bit <= '1';
+        count_right <= '0';
+        wait for clk_period;
+        assert result = x"0000000000000020"
+            report "bad cntlzw 0 = " & to_hstring(result);
+        count_right <= '1';
+        wait for clk_period;
+        assert result = x"0000000000000020"
+            report "bad cnttzw 0 = " & to_hstring(result);
+
+        report "test cntlzd/w";
+        count_right <= '0';
+        for j in 0 to 100 loop
+            r := pseudorand(64);
+            r(63) := '1';
+            for i in 0 to 63 loop
+                rs <= r;
+                is_32bit <= '0';
+                wait for clk_period;
+                assert to_integer(unsigned(result)) = i
+                    report "bad cntlzd " & to_hstring(rs) & " -> " & to_hstring(result);
+                rs <= r(31 downto 0) & r(63 downto 32);
+                is_32bit <= '1';
+                wait for clk_period;
+                if i < 32 then
+                    assert to_integer(unsigned(result)) = i
+                        report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result);
+                else
+                    assert to_integer(unsigned(result)) = 32
+                        report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result);
+                end if;
+                r := '0' & r(63 downto 1);
+            end loop;
+        end loop;
+
+        report "test cnttzd/w";
+        count_right <= '1';
+        for j in 0 to 100 loop
+            r := pseudorand(64);
+            r(0) := '1';
+            for i in 0 to 63 loop
+                rs <= r;
+                is_32bit <= '0';
+                wait for clk_period;
+                assert to_integer(unsigned(result)) = i
+                    report "bad cnttzd " & to_hstring(rs) & " -> " & to_hstring(result);
+                is_32bit <= '1';
+                wait for clk_period;
+                if i < 32 then
+                    assert to_integer(unsigned(result)) = i
+                        report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result);
+                else
+                    assert to_integer(unsigned(result)) = 32
+                        report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result);
+                end if;
+                r := r(62 downto 0) & '0';
+            end loop;
+        end loop;
+
+        assert false report "end of test" severity failure;
+        wait;
+    end process;
+end behave;