From 4d5abfb430d1a08c3ff8920381ceb5a498231910 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 29 Aug 2019 09:47:45 +1000 Subject: [PATCH] Remove dynamic ranges from code 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 --- execute1.vhdl | 24 +++++++-- helpers.vhdl | 8 +-- loadstore2.vhdl | 14 ++++- ppc_fx_insns.vhdl | 126 ++++++++++++++++++++++++++++++++++++--------- scripts/verific.sh | 26 ++++++++++ 5 files changed, 164 insertions(+), 34 deletions(-) create mode 100755 scripts/verific.sh diff --git a/execute1.vhdl b/execute1.vhdl index 0069465..e57dd4f 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -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'; diff --git a/helpers.vhdl b/helpers.vhdl index 94cb9fd..f0bce95 100644 --- a/helpers.vhdl +++ b/helpers.vhdl @@ -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; diff --git a/loadstore2.vhdl b/loadstore2.vhdl index 7aede4a..ac63bca 100644 --- a/loadstore2.vhdl +++ b/loadstore2.vhdl @@ -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))); diff --git a/ppc_fx_insns.vhdl b/ppc_fx_insns.vhdl index 9b23bc1..ea42b6d 100644 --- a/ppc_fx_insns.vhdl +++ b/ppc_fx_insns.vhdl @@ -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 index 0000000..c657679 --- /dev/null +++ b/scripts/verific.sh @@ -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