2014-09-10 123 views
0
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
--use IEEE.STD_LOGIC_ARITH.ALL; 
--use IEEE.STD_LOGIC_UNSIGNED.ALL; 
use IEEE.NUMERIC_STD.ALL; 

entity two_number_split is 
    Port (number : in integer range 0 to 99; 
      position0 : out STD_LOGIC_VECTOR (3 downto 0); 
      position1 : out STD_LOGIC_VECTOR (3 downto 0)); 
end two_number_split; 

architecture Behavioral of two_number_split is 
    signal pos0, pos1 : STD_LOGIC_VECTOR(3 downto 0); 
begin 
    convert: process(number, pos0, pos1) 
    begin 
      pos1 <= number/10; 
      pos0 <= number mod 10; 
      position0 <= std_logic_vector(pos0); 
      position1 <= std_logic_vector(pos1); 
    end process convert; 

end Behavioral; 

错误:什么VHDL库使用十进制模

ERROR:HDLCompiler:1638 - "C:\Users\XXX\Documents\SS\ISE_Ex\seven_segment\two_numbers.vhd" Line 19: found '0' definitions of operator "/", cannot determine exact overloaded matching definition for "/" 
ERROR:HDLCompiler:1638 - "C:\Users\XXX\Documents\SS\ISE_Ex\seven_segment\two_numbers.vhd" Line 20: found '0' definitions of operator "mod", cannot determine exact overloaded matching definition for "mod" 

我想我只是使用了错误的库。任何建议吗?我已经尝试了上面列出的库的所有组合,不知道发生了什么。

回答

1

std_logic_vector传统上不是数字类型。它是一些位数的集合,故意忽略数字运算符来强化这种解释。您应该使用numeric_std中的unsignedsigned类型来获取具有一组算术运算符的数组。

(可选)如果您的工具支持VHDL-2008,则可以使用ieee.numeric_std_unsigned将算术语义添加到std_logic_vector。它与std_logic_unsigned类似,尽管它的名称和库映射不是标准库。

+0

我知道一个逻辑向量是一个位数组。但我正在取一个十进制数并将其分成两个代表每个数字的位数组。 IE浏览器。 99的输入将使得pos0 1001和pos1 1001. – marshmallow 2014-09-10 22:56:01

+0

如果你使用定义了除法和mod运算符的类型,就会发生这种情况。您有两种选择可以用我的答案中描述的标准库来完成这一任务。看起来您可能试图将其输出到七段显示器,在这种情况下,您可能希望使用不需要任何除法的双重算法转换为BCD。 – 2014-09-10 23:28:34

2

您可以修改pos0pos1的声明为整数类型,计算并将它们转换为BCD表示形式。

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity two_number_split is 
    port ( 
     number:  in integer range 0 to 99; 
     position0: out std_logic_vector (3 downto 0); 
     position1: out std_logic_vector (3 downto 0) 
    ); 
end two_number_split; 

architecture Behavioral of two_number_split is 
    signal pos0, pos1 : natural range 0 to 9; -- std_logic_vector(3 downto 0); 
begin 
    convert: process(number, pos0, pos1) 
    begin 
      pos1 <= number/10; 
      pos0 <= number mod 10; 
      position0 <= std_logic_vector(to_unsigned(pos0,position0'LENGTH)); 
      -- was <= std_logic_vector(pos0); 
      position1 <= std_logic_vector(to_unsigned(pos1,position1'LENGTH)); 
      -- was <= std_logic_vector(pos1); 
    end process convert; 

end Behavioral; 

它使用to_unsigned于十进制数位值POS1和POS0转换为unsigned数组类型。返回的unsigned数组长度由第二个参数指定,该参数可能只是一个文字。

您可以使用unsigned作为position0position1的类型,并为每个作业保存类型转换。

这里的想法有三个方面:可读性,使用兼容左右参数的操作符函数以及返回值,以及使用integer乘法运算符的速度快于unsigned运算符。无符号运算暗含在number的自然范围内。

而这个例子的工作原理:

tb_numb_split.png

但并不特别合成资格 - 有两个相乘的运营商。如果您需要综合某些内容,请参阅Convert 8bit binary number to BCD in VHDL以获取有关如何避免七位乘法运算符的启示。

+0

只需注意。虽然在一般情况下该部门对合成有问题,但XST确实支持6系列和7系列系列的非幂次幂常量推导的divmod的合成。我很好奇它是如何执行的,并且结果适合7位输入的7个LUT,这与手动实现的两位BCD转换相同。其他供应商可能会对不断的分裂提供类似支持 – 2014-09-11 13:07:37

+0

@KevinThibedeau - [UG687](http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_1/xst_v6s6.pdf)P.77,在2的恒定功率下支持'mod','/'“如果右操作数是2的常数幂,或者如果两个操作数是恒定的,则支持。 '数字'不是一个常数,这两种情况都不是真的,我很惊喜 - 但它适合放在一张桌子上,即足够小到浓缩咖啡。对于add3,可以采用6个LUT,BIN(7)为常数'0'(7位输入),并且是移位和条件添加(除法步骤)。在程序框图中add3 U0不需要,输入不能大于4. – user1155120 2014-09-11 14:29:48

+0

我很惊讶地发现它的工作原理,因为那是我对文档的回忆。它看起来好像是在RTL视图中合成完整的分割或模数操作,然后合并共享路径并优化大部分路径,因为在这种情况下只保留较低的四位。 – 2014-09-11 16:45:56

相关问题