aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiretza <xiretza@xiretza.xyz>2020-03-21 20:51:03 +0100
committertgingold <tgingold@users.noreply.github.com>2020-03-22 08:13:31 +0100
commitc975230114caebe442e0ec403796771caf70925d (patch)
treedc0b9047ead4b79df095e3c22ed4f5dd4f7ac5aa
parent63bb08a0893209bd0b1f13e9ab5c3e585ed43514 (diff)
downloadghdl-yosys-plugin-c975230114caebe442e0ec403796771caf70925d.tar.gz
ghdl-yosys-plugin-c975230114caebe442e0ec403796771caf70925d.tar.bz2
ghdl-yosys-plugin-c975230114caebe442e0ec403796771caf70925d.zip
Add min/max gates
-rw-r--r--src/ghdl.cc21
-rw-r--r--testsuite/formal/gates/test_minmax.sby12
-rw-r--r--testsuite/formal/gates/test_minmax.vhd57
-rwxr-xr-xtestsuite/formal/gates/testsuite.sh2
4 files changed, 91 insertions, 1 deletions
diff --git a/src/ghdl.cc b/src/ghdl.cc
index 9322ad8..28107d4 100644
--- a/src/ghdl.cc
+++ b/src/ghdl.cc
@@ -563,6 +563,10 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m)
case Id_Lsr:
case Id_Lsl:
case Id_Asr:
+ case Id_Smin:
+ case Id_Umin:
+ case Id_Smax:
+ case Id_Umax:
case Id_Smul:
case Id_Umul:
case Id_Sdiv:
@@ -733,6 +737,23 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m)
case Id_Asr:
module->addSshr(to_str(iname), IN(0), IN(1), OUT(0), true);
break;
+ case Id_Smin:
+ case Id_Umin:
+ case Id_Smax:
+ case Id_Umax:
+ {
+ bool is_signed = (id == Id_Smin || id == Id_Smax);
+
+ RTLIL::Wire *select_rhs = module->addWire(NEW_ID);
+ if (id == Id_Smin || id == Id_Umin) {
+ module->addGt(NEW_ID, IN(0), IN(1), select_rhs, is_signed);
+ } else {
+ module->addLt(NEW_ID, IN(0), IN(1), select_rhs, is_signed);
+ }
+
+ module->addMux(to_str(iname), IN(0), IN(1), select_rhs, OUT(0));
+ }
+ break;
case Id_Smul:
module->addMul(to_str(iname), IN(0), IN(1), OUT(0), true);
break;
diff --git a/testsuite/formal/gates/test_minmax.sby b/testsuite/formal/gates/test_minmax.sby
new file mode 100644
index 0000000..c7d103a
--- /dev/null
+++ b/testsuite/formal/gates/test_minmax.sby
@@ -0,0 +1,12 @@
+[options]
+mode prove
+
+[engines]
+smtbmc z3
+
+[script]
+ghdl --std=08 test_minmax.vhd -e ent
+prep -top ent
+
+[files]
+test_minmax.vhd
diff --git a/testsuite/formal/gates/test_minmax.vhd b/testsuite/formal/gates/test_minmax.vhd
new file mode 100644
index 0000000..8cd760c
--- /dev/null
+++ b/testsuite/formal/gates/test_minmax.vhd
@@ -0,0 +1,57 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity ent is
+ port (
+ clk : in std_logic;
+ a : in std_logic_vector(7 downto 0);
+ b : in std_logic_vector(7 downto 0);
+ min_sgn : out signed(7 downto 0);
+ max_sgn : out signed(7 downto 0);
+ min_uns : out unsigned(7 downto 0);
+ max_uns : out unsigned(7 downto 0)
+ );
+end;
+
+architecture a of ent is
+begin
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ min_sgn <= minimum(signed(a), signed(b));
+ max_sgn <= maximum(signed(a), signed(b));
+
+ min_uns <= minimum(unsigned(a), unsigned(b));
+ max_uns <= maximum(unsigned(a), unsigned(b));
+ end if;
+ end process;
+
+ formal: block
+ signal prev_a : std_logic_vector(7 downto 0);
+ signal prev_b : std_logic_vector(7 downto 0);
+ signal has_run : std_logic := '0';
+ begin
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ has_run <= '1';
+ prev_a <= a;
+ prev_b <= b;
+ end if;
+ end process;
+
+ default clock is rising_edge(clk);
+ assert eventually! has_run;
+
+ assert always has_run and signed(prev_a) <= signed(prev_b) ->
+ min_sgn = signed(prev_a) and max_sgn = signed(prev_b);
+ assert always has_run and signed(prev_a) >= signed(prev_b) ->
+ min_sgn = signed(prev_b) and max_sgn = signed(prev_a);
+
+ assert always has_run and unsigned(prev_a) <= unsigned(prev_b) ->
+ min_uns = unsigned(prev_a) and max_uns = unsigned(prev_b);
+ assert always has_run and unsigned(prev_a) >= unsigned(prev_b) ->
+ min_uns = unsigned(prev_b) and max_uns = unsigned(prev_a);
+ end block;
+end;
diff --git a/testsuite/formal/gates/testsuite.sh b/testsuite/formal/gates/testsuite.sh
index 7986d8c..d4bcf98 100755
--- a/testsuite/formal/gates/testsuite.sh
+++ b/testsuite/formal/gates/testsuite.sh
@@ -3,7 +3,7 @@
topdir=../..
. $topdir/testenv.sh
-for f in abs lsl lsr asr; do
+for f in abs minmax lsl lsr asr; do
formal "test_${f}"
done