diff --git a/Makefile b/Makefile index 2694556..43f1634 100644 --- 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 index 0000000..91de334 --- /dev/null +++ b/countzero_tb.vhdl @@ -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;