2014-09-10 3 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 традиционно не является числовым. Это набор битов, и числовые операторы были намеренно упущены, чтобы укрепить эту интерпретацию. Вы должны использовать типы unsigned или signed от numeric_std, чтобы получить массивы с набором арифметических операторов.

Возможно, если ваши инструменты поддерживают VHDL-2008, вы можете использовать ieee.numeric_std_unsigned, чтобы добавить арифметическую семантику к std_logic_vector. Он похож на std_logic_unsigned, который, несмотря на то, что его имя и библиотечное сопоставление не являются стандартной библиотекой.

+0

Я знаю, что логический вектор представляет собой массив бит. Но я принимаю десятичное число и разбиваю его на два битовых массива, представляющих каждое число. То есть. вход 99 сделает pos0 1001 и pos1 1001. – marshmallow

+0

Это произойдет, если вы используете тип с определенными операторами разделения и мод. У вас есть два варианта, чтобы выполнить это со стандартными библиотеками, как описано в моем ответе. Похоже, вы потенциально пытаетесь вывести это на семисегментный дисплей, и в этом случае вы, возможно, захотите перейти на преобразование в BCD, используя алгоритм с двойной ошибкой, который не требует какого-либо деления. –

2

Вы можете изменить объявления pos0 и pos1 как целочисленные, вычислить и затем преобразовать их в представление 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 как тип для position0 и position1 и сохранять преобразования типов для каждого задания.

Идея здесь в трех аспектах: читаемость, использование операторских функций с совместимыми левым и правым аргументами, а также возвращаемое значение, а также использование операторов integer, которые быстрее, чем unsigned. Неподписанная операция подразумевается естественным диапазоном number.

И этот пример работает:

tb_numb_split.png

Но не особенно синтез право - наличие двух умножаются операторов. Если вам нужно что-то синтезировать, обратитесь к Convert 8bit binary number to BCD in VHDL за вдохновение в том, как избежать семиразрядных операторов умножения.

+0

Просто отметить. В то время как разделение является проблематичным для синтеза в общем случае, XST поддерживает синтез выводимого divmod константами без силы двух для семейств 6 и 7 рядов. Мне было любопытно посмотреть, как оно выполняется, и результат вписывается в 7 LUT для 7-битного ввода, так же, как и вручную преобразованное двузначное преобразование BCD. Другие поставщики могут иметь аналогичную поддержку для постоянного разделения. –

+0

@KevinThibedeau - [UG687] (http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_1/xst_v6s6.pdf) P.77, 'mod' поддерживается для постоянной мощности 2,'/'" Поддерживается, если правый операнд является постоянной мощностью 2 или оба операнда постоянны ". 'number' не является константой, ни один случай не является истинным, я приятно удивлен, но он подходит в таблице, то есть достаточно мал для эспрессо. Это может занять 6 LUT для add3 с BIN (7) константой '0' (7-битный ввод) и сдвигом и условным добавлением (делением). add3 U0 на блок-диаграмме не требуется, вход не может быть больше 4. – user1155120

+0

Я был так же удивлен, увидев, что он работает, потому что это было мое воспоминание о документации. Это похоже на то, что он синтезирует полную операцию разделения или модуля в представлении RTL, затем объединяет общие пути и оптимизирует большинство из них, так как в этом случае сохраняются только нижние четыре бита. –

Смежные вопросы