Remove dynamic ranges from code
authorMichael Neuling <mikey@neuling.org>
Wed, 28 Aug 2019 23:47:45 +0000 (09:47 +1000)
committerMichael Neuling <mikey@neuling.org>
Fri, 30 Aug 2019 06:13:48 +0000 (16:13 +1000)
Some VHDL compilers like verific [1] don't like these, so let's remove
them. Lots of random code changes, but passes make check.

Also add basic script to run verific and generate verilog.

1. https://www.verific.com/

Signed-off-by: Michael Neuling <mikey@neuling.org>
execute1.vhdl
helpers.vhdl
loadstore2.vhdl
ppc_fx_insns.vhdl
scripts/verific.sh [new file with mode: 0755]

index 00694652f5ed1e12bd76f1818674baebb19b9199..e57dd4fc91f20d6d8184bc865ac638f244c73be0 100644 (file)
@@ -43,6 +43,7 @@ begin
                variable result_with_carry : std_ulogic_vector(64 downto 0);
                variable result_en : integer;
                variable crnum : integer;
+               variable lo, hi : integer;
        begin
                result := (others => '0');
                result_with_carry := (others => '0');
@@ -114,14 +115,20 @@ begin
                                        e_out.write_cr_enable <= '1';
                                        crnum := to_integer(unsigned(e.const1(2 downto 0)));
                                        e_out.write_cr_mask <= num_to_fxm(crnum);
-                                       e_out.write_cr_data <= (others => '0');
-                                       e_out.write_cr_data((4*(7-crnum)+3) downto (4*(7-crnum))) <= ppc_cmp(e.const2(0), e.read_data1, e.read_data2);
+                                       for i in 0 to 7 loop
+                                               lo := i*4;
+                                               hi := lo + 3;
+                                               e_out.write_cr_data(hi downto lo) <= ppc_cmp(e.const2(0), e.read_data1, e.read_data2);
+                                       end loop;
                                when OP_CMPL =>
                                        e_out.write_cr_enable <= '1';
                                        crnum := to_integer(unsigned(e.const1(2 downto 0)));
                                        e_out.write_cr_mask <= num_to_fxm(crnum);
-                                       e_out.write_cr_data <= (others => '0');
-                                       e_out.write_cr_data((4*(7-crnum)+3) downto (4*(7-crnum))) <= ppc_cmpl(e.const2(0), e.read_data1, e.read_data2);
+                                       for i in 0 to 7 loop
+                                               lo := i*4;
+                                               hi := lo + 3;
+                                               e_out.write_cr_data(hi downto lo) <= ppc_cmpl(e.const2(0), e.read_data1, e.read_data2);
+                                       end loop;
                                when OP_CNTLZW =>
                                        result := ppc_cntlzw(e.read_data1);
                                        result_en := 1;
@@ -173,7 +180,14 @@ begin
                                when OP_MFOCRF =>
                                        crnum := fxm_to_num(e.const1(7 downto 0));
                                        result := (others => '0');
-                                       result((4*(7-crnum)+3) downto (4*(7-crnum))) := e.cr((4*(7-crnum)+3) downto (4*(7-crnum)));
+--                                     result((4*(7-crnum)+3) downto (4*(7-crnum))) := e.cr((4*(7-crnum)+3) downto (4*(7-crnum))); FIXME
+                                       for i in 0 to 7 loop
+                                               lo := (7-i)*4;
+                                               hi := lo + 3;
+                                               if crnum = i then
+                                                       result(hi downto lo) := e.cr(hi downto lo);
+                                               end if;
+                                       end loop;
                                        result_en := 1;
                                when OP_MTCRF =>
                                        e_out.write_cr_enable <= '1';
index 94cb9fd0a663ac111768e5445ec0bd2865357885..f0bce953498b9cfc06f8a7f2d3573b3e423928cd 100644 (file)
@@ -194,16 +194,16 @@ package body helpers is
        begin
                case_0: case size is
                        when 2 =>
-                               upper := 15;
+                               ret := resize(signed(val(15 downto 0)), 64);
                        when 4 =>
-                               upper := 31;
+                               ret := resize(signed(val(31 downto 0)), 64);
                        when 8 =>
-                               upper := 63;
+                               ret := resize(signed(val(63 downto 0)), 64);
                        when others =>
                                report "bad byte reverse length " & integer'image(size) severity failure;
                end case;
 
-               ret := resize(signed(val(upper downto 0)), 64);
                return std_ulogic_vector(ret);
+
        end;
 end package body helpers;
index 7aede4a6e296bc4b2e21fa8af9f054155a1d23aa..ac63bca356c970afad6b75881d4c6c1c588f3880 100644 (file)
@@ -113,7 +113,19 @@ begin
                        when WAITING_FOR_READ_ACK =>
                                if m_in.ack = '1' then
                                        tmp := std_logic_vector(shift_right(unsigned(m_in.dat), wishbone_data_shift(l_saved.addr)));
-                                       data((to_integer(unsigned(l_saved.length))*8-1) downto 0) := tmp((to_integer(unsigned(l_saved.length))*8-1) downto 0);
+                                       case to_integer(unsigned(l_saved.length)) is
+                                       when 0 =>
+                                       when 1 =>
+                                               data(7 downto 0) := tmp(7 downto 0);
+                                       when 2 =>
+                                               data(15 downto 0) := tmp(15 downto 0);
+                                       when 4 =>
+                                               data(31 downto 0) := tmp(31 downto 0);
+                                       when 8 =>
+                                               data(63 downto 0) := tmp(63 downto 0);
+                                       when others =>
+                                               assert false report "invalid length" severity failure;
+                                       end case;
 
                                        if l_saved.sign_extend = '1' then
                                                data := sign_extend(data, to_integer(unsigned(l_saved.length)));
index 9b23bc14bf68f6b6a0c19531abe95be8a6fa8462..ea42b6d0a2f03b3278e94450d343d8ed0903b626 100644 (file)
@@ -339,10 +339,17 @@ package body ppc_fx_insns is
                tmp2 := (others => '0');
                if hi < lo then
                        -- Mask wraps around
-                       tmp2(63 downto lo) := tmp1(63 downto lo);
-                       tmp2(hi downto 0) := tmp1(hi downto 0);
+                       for i in 0 to 63 loop
+                               if i <= hi or i >= lo then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                else
-                       tmp2(hi downto lo) := tmp1(hi downto lo);
+                       for i in 0 to 63 loop
+                               if i >= lo and i <= hi then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                end if;
                return tmp2;
        end;
@@ -360,10 +367,17 @@ package body ppc_fx_insns is
                tmp2 := (others => '0');
                if hi < lo then
                        -- Mask wraps around
-                       tmp2(63 downto lo) := tmp1(63 downto lo);
-                       tmp2(hi downto 0) := tmp1(hi downto 0);
+                       for i in 0 to 63 loop
+                               if i <= hi or i >= lo then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                else
-                       tmp2(hi downto lo) := tmp1(hi downto lo);
+                       for i in 0 to 63 loop
+                               if i >= lo and i <= hi then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                end if;
                return tmp2;
        end;
@@ -379,10 +393,17 @@ package body ppc_fx_insns is
                tmp2 := ra;
                if hi < lo then
                        -- Mask wraps around
-                       tmp2(63 downto lo) := tmp1(63 downto lo);
-                       tmp2(hi downto 0) := tmp1(hi downto 0);
+                       for i in 0 to 63 loop
+                               if i <= hi or i >= lo then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                else
-                       tmp2(hi downto lo) := tmp1(hi downto lo);
+                       for i in 0 to 63 loop
+                               if i >= lo and i <= hi then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                end if;
                return tmp2;
        end;
@@ -394,7 +415,11 @@ package body ppc_fx_insns is
                hi := 63-to_integer(unsigned(mb));
                tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
                tmp2 := (others => '0');
-               tmp2(hi downto 0) := tmp1(hi downto 0);
+               for i in 0 to 63 loop
+                       if i <= hi then
+                               tmp2(i) := tmp1(i);
+                       end if;
+               end loop;
                return tmp2;
        end;
 
@@ -405,7 +430,11 @@ package body ppc_fx_insns is
                lo := 63-to_integer(unsigned(me));
                tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
                tmp2 := (others => '0');
-               tmp2(63 downto lo) := tmp1(63 downto lo);
+               for i in 0 to 63 loop
+                       if i >= lo then
+                               tmp2(i) := tmp1(i);
+                       end if;
+               end loop;
                return tmp2;
        end;
 
@@ -419,10 +448,17 @@ package body ppc_fx_insns is
                tmp2 := (others => '0');
                if hi < lo then
                        -- Mask wraps around
-                       tmp2(63 downto lo) := tmp1(63 downto lo);
-                       tmp2(hi downto 0) := tmp1(hi downto 0);
+                       for i in 0 to 63 loop
+                               if i <= hi or i >= lo then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                else
-                       tmp2(hi downto lo) := tmp1(hi downto lo);
+                       for i in 0 to 63 loop
+                               if i >= lo and i <= hi then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                end if;
                return tmp2;
        end;
@@ -434,7 +470,11 @@ package body ppc_fx_insns is
                hi := 63-to_integer(unsigned(mb));
                tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
                tmp2 := (others => '0');
-               tmp2(hi downto 0) := tmp1(hi downto 0);
+               for i in 0 to 63 loop
+                       if i <= hi then
+                               tmp2(i) := tmp1(i);
+                       end if;
+               end loop;
                return tmp2;
        end;
 
@@ -445,7 +485,11 @@ package body ppc_fx_insns is
                lo := 63-to_integer(unsigned(me));
                tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
                tmp2 := (others => '0');
-               tmp2(63 downto lo) := tmp1(63 downto lo);
+               for i in 0 to 63 loop
+                       if i >= lo then
+                               tmp2(i) := tmp1(i);
+                       end if;
+               end loop;
                return tmp2;
        end;
 
@@ -459,10 +503,17 @@ package body ppc_fx_insns is
                tmp2 := ra;
                if hi < lo then
                        -- Mask wraps around
-                       tmp2(63 downto lo) := tmp1(63 downto lo);
-                       tmp2(hi downto 0) := tmp1(hi downto 0);
+                       for i in 0 to 63 loop
+                               if i <= hi or i >= lo then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                else
-                       tmp2(hi downto lo) := tmp1(hi downto lo);
+                       for i in 0 to 63 loop
+                               if i >= lo and i <= hi then
+                                       tmp2(i) := tmp1(i);
+                               end if;
+                       end loop;
                end if;
                return tmp2;
        end;
@@ -490,12 +541,19 @@ package body ppc_fx_insns is
        function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
                variable n : integer;
                variable tmp : signed(31 downto 0);
+               variable mask : std_ulogic_vector(63 downto 0);
                variable carry: std_ulogic;
        begin
                n := to_integer(unsigned(sh));
                tmp := shift_right(signed(rs(31 downto 0)), n);
                -- what about n = 0?
-               carry := or rs(n-1 downto 0) and rs(31);
+               mask := (others => '0');
+               for i in 0 to 63 loop
+                       if i < n then
+                               mask(i) := '1';
+                       end if;
+               end loop;
+               carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(31);
 
                return carry & std_ulogic_vector(resize(tmp, rs'length));
        end;
@@ -503,13 +561,19 @@ package body ppc_fx_insns is
        function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
                variable n : natural;
                variable tmp : signed(31 downto 0);
+               variable mask : std_ulogic_vector(63 downto 0);
                variable carry: std_ulogic;
        begin
                n := to_integer(unsigned(rb(5 downto 0)));
                tmp := shift_right(signed(rs(31 downto 0)), n);
                -- what about n = 0?
-               carry := or rs(n-1 downto 0) and rs(31);
-
+               mask := (others => '0');
+               for i in 0 to 63 loop
+                       if i < n then
+                               mask(i) := '1';
+                       end if;
+               end loop;
+               carry := or (rs and mask) and rs(31);
                return carry & std_ulogic_vector(resize(tmp, rs'length));
        end;
 
@@ -530,10 +594,17 @@ package body ppc_fx_insns is
        function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
                variable n : integer;
                variable carry: std_ulogic;
+               variable mask : std_ulogic_vector(63 downto 0);
        begin
                n := to_integer(unsigned(sh));
                -- what about n = 0?
-               carry := or rs(n-1 downto 0) and rs(63);
+               mask := (others => '0');
+               for i in 0 to 63 loop
+                       if i < n then
+                               mask(i) := '1';
+                       end if;
+               end loop;
+               carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63);
 
                return carry & std_ulogic_vector(shift_right(signed(rs), n));
        end;
@@ -541,10 +612,17 @@ package body ppc_fx_insns is
        function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
                variable n : integer;
                variable carry: std_ulogic;
+               variable mask : std_ulogic_vector(63 downto 0);
        begin
                n := to_integer(unsigned(rb(6 downto 0)));
                -- what about n = 0?
-               carry := or rs(n-1 downto 0) and rs(63);
+               mask := (others => '0');
+               for i in 0 to 63 loop
+                       if i < n then
+                               mask(i) := '1';
+                       end if;
+               end loop;
+               carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63);
 
                return carry & std_ulogic_vector(shift_right(signed(rs), n));
        end;
diff --git a/scripts/verific.sh b/scripts/verific.sh
new file mode 100755 (executable)
index 0000000..c657679
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+D=$(dirname $0)
+
+TCL=$(mktemp)
+
+VERIFICDIR=$(dirname $(dirname $(which verific-linux)))
+
+echo "setvhdllibrarypath -default $VERIFICDIR/vhdl_packages/vdbs_2008" >> $TCL
+
+# FIXME: make this list dynamic
+for i in decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl fetch2.vhdl decode1.vhdl helpers.vhdl  decode2.vhdl register_file.vhdl  cr_file.vhdl crhelpers.vhdl ppc_fx_insns.vhdl sim_console.vhdl execute1.vhdl execute2.vhdl loadstore1.vhdl  loadstore2.vhdl multiply.vhdl writeback.vhdl wishbone_arbiter.vhdl core.vhdl simple_ram_behavioural_helpers.vhdl simple_ram_behavioural.vhdl core_tb.vhdl; do
+    F=$(realpath $D/../$i)
+    echo "analyze -format vhdl -vhdl_2008 $F" >> $TCL
+done
+
+echo "elaborate core" >> $TCL
+echo "write core.v" >> $TCL
+echo "area" >> $TCL
+echo "optimize -hierarchy -constant -cse -operator -dangling -resource" >> $TCL
+echo "area" >> $TCL
+echo "write core-optimised.v" >> $TCL
+
+verific-linux -script_file $TCL
+
+rm -rf $TCL