From 9bc72cc9dce5ea975e3ae80826c2e6db044f29ff Mon Sep 17 00:00:00 2001 From: Jan Decaluwe Date: Sat, 18 Jul 2015 10:33:17 +0200 Subject: [PATCH] Support ternary operator without VHDL 2008 #107 --- myhdl/conversion/_toVHDL.py | 9 +++-- myhdl/conversion/_toVHDLPackage.py | 33 +++++++++++++++++++ myhdl/test/conversion/general/test_ternary.py | 6 ++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/myhdl/conversion/_toVHDL.py b/myhdl/conversion/_toVHDL.py index dd51c1b7..68fe5225 100644 --- a/myhdl/conversion/_toVHDL.py +++ b/myhdl/conversion/_toVHDL.py @@ -1105,11 +1105,13 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): def visit_IfExp(self, node): # propagate the node's vhd attribute node.body.vhd = node.orelse.vhd = node.vhd + self.write('tern_op(') self.visit(node.body) - self.write(' when ') + self.write(', cond => ') self.visit(node.test) - self.write(' else ') + self.write(', if_false => ') self.visit(node.orelse) + self.write(')') def visit_For(self, node): self.labelStack.append(node.breakLabel) @@ -1288,7 +1290,8 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin): if isinstance(node.vhd, vhd_std_logic): s = "'Z'" else: - s = "(others => 'Z')" + assert hasattr(node.vhd, 'size') + s = "(%d downto 0 => 'Z')" % (node.vhd.size-1) elif n in self.tree.vardict: s = n obj = self.tree.vardict[n] diff --git a/myhdl/conversion/_toVHDLPackage.py b/myhdl/conversion/_toVHDLPackage.py index 86f7d46e..59199ed8 100644 --- a/myhdl/conversion/_toVHDLPackage.py +++ b/myhdl/conversion/_toVHDLPackage.py @@ -58,6 +58,12 @@ package pck_myhdl_%(version)s is function "-" (arg: unsigned) return signed; + function tern_op(if_true: std_logic; cond: boolean; if_false: std_logic) return std_logic; + + function tern_op(if_true: unsigned; cond: boolean; if_false: unsigned) return unsigned; + + function tern_op(if_true: signed; cond: boolean; if_false: signed) return signed; + end pck_myhdl_%(version)s; @@ -157,6 +163,33 @@ package body pck_myhdl_%(version)s is return - signed(resize(arg, arg'length+1)); end function "-"; + function tern_op(if_true: std_logic; cond: boolean; if_false: std_logic) return std_logic is + begin + if cond then + return if_true; + else + return if_false; + end if; + end function tern_op; + + function tern_op(if_true: unsigned; cond: boolean; if_false: unsigned) return unsigned is + begin + if cond then + return if_true; + else + return if_false; + end if; + end function tern_op; + + function tern_op(if_true: signed; cond: boolean; if_false: signed) return signed is + begin + if cond then + return if_true; + else + return if_false; + end if; + end function tern_op; + end pck_myhdl_%(version)s; """ % {'version' : _shortversion} diff --git a/myhdl/test/conversion/general/test_ternary.py b/myhdl/test/conversion/general/test_ternary.py index c8e865f8..ec88343a 100644 --- a/myhdl/test/conversion/general/test_ternary.py +++ b/myhdl/test/conversion/general/test_ternary.py @@ -66,9 +66,11 @@ def TernaryBench(ternary): # uncomment when we have a VHDL-2008 compliant simulator -# def test_ternary1(): -# assert conversion.verify(TernaryBench, ternary1) == 0 +def test_ternary1(): + toVHDL.name = 'ternary1' + assert conversion.verify(TernaryBench, ternary1) == 0 def test_ternary2(): + toVHDL.name = 'ternary2' assert conversion.verify(TernaryBench, ternary2) == 0