2016-07-14 6 views
0

Я столкнулся с проблемой преобразования/прочитал много похожих тем, но мой код все еще не работает. Не могли бы вы дать мне несколько советов. Quartus дать мне ошибку:std_logic_vector для целочисленного преобразования vhdl

Error (10476): VHDL error at true_dual_port_ram_single_clock.vhd(44): type of identifier "random_num_i" does not agree with its usage as "std_logic_vector" type

LIBRARY ieee; 
USE ieee.std_logic_1164.all; 
use IEEE.std_logic_signed.all; 
use IEEE.std_logic_unsigned.all; 
use IEEE.NUMERIC_STD.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 

entity write_ram is 
    generic(width : integer := 32); 
    port(clock_i : IN STD_LOGIC; 
     we_w  : IN STD_LOGIC; 
     wr_addr : IN INTEGER RANGE 0 to 31; 
     read_add : IN INTEGER RANGE 0 to 31; 
     q_out : out STD_LOGIC_VECTOR(2 DOWNTO 0) 
); 
end write_ram; 

architecture rtl of write_ram is 
    --- Component decalarartion 
    component random is 
    port(clk  : in std_logic; 
     random_num : out std_logic_vector(width - 1 downto 0) --output vector 
    ); 
    end component; 

    component single_clock_ram is 
    port(clock   : IN STD_LOGIC; 
     data   : IN INTEGER RANGE 0 to 31; 
     write_address : IN INTEGER RANGE 0 to 31; 
     read_address : IN INTEGER RANGE 0 to 31; 
     we   : IN STD_LOGIC; 
     q    : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) 
    ); 
    end component; 
    for all : random use entity work.random(rtl); 
    for all : single_clock_ram use entity work.single_clock_ram(rtl); 
    Signal random_num_i : INTEGER RANGE 0 to 31; --interanal signals 
begin 
    -- Component Instantiation 

    C1 : random Port map(
     clk  => clock_i, 
     --random_num <=to_integer(to_signed(random_num_i)) 
     random_num => random_num_i 
    ); 
    random_num <= to_integer(to_signed(random_num_i)); -- error 

    C2 : single_clock_ram 
    Port map(
     clock   => clock_i, 
     we   => we_w, 
     read_address => read_add, 
     write_address => wr_addr, 
     data   => random_num_i, 
     q    => q_out 
    ); 

end rtl; 

ответ

1

Ваш вопрос не является MCVE со спецификациями конфигурации для случайных и single_clock_ram настоящего времени. Вы не предоставили им декларации объектов и архитектуры (rtl).

С ними закомментированы этим анализом:

library ieee; 
use ieee.std_logic_1164.all; 
-- use ieee.std_logic_signed.all; -- NOT USED 
-- use ieee.std_logic_unsigned.all; -- NOT USED 
use ieee.numeric_std.all; 
-- use ieee.std_logic_arith.all; -- NOT USED 

entity write_ram is 
    generic (width: integer := 32); 
    port (clock_i: in std_logic; 
     we_w:  in std_logic; 
     wr_addr: in integer range 0 to 31; 
     read_add: in integer range 0 to 31; 
     q_out:  out std_logic_vector(2 downto 0) 
); 
end entity write_ram; 

architecture rtl of write_ram is 
    --- component declaration 
    component random is 
    port (clk:   in std_logic; 
     random_num: out std_logic_vector(width - 1 downto 0) --output vector 
    ); 
    end component; 

    component single_clock_ram is 
    port (clock:   in std_logic; 
      data:   in integer range 0 to 31; 
      write_address: in integer range 0 to 31; 
      read_address: in integer range 0 to 31; 
      we:    in std_logic; 
      q:    out std_logic_vector(2 downto 0) 
    ); 
    end component; 
    -- for all: random use entity work.random(rtl); 
    -- for all: single_clock_ram use entity work.single_clock_ram(rtl); 
    signal random_num_i: integer range 0 to 31; -- internal signals 
    signal random_num: std_logic_vector(width - 1 downto 0); -- added 
begin 
    -- component instantiation 

    c1: random port map (
     clk  => clock_i, 
     -- random_num <=to_integer(to_signed(random_num_i)) 
     -- random_num => random_num_i -- DELETED 
     random_num => random_num -- ADDED 
    ); 
    -- random_num <= to_integer(to_signed(random_num_i)); -- error DELETED 
    random_num_i <= to_integer(signed(random_num)); -- ADDED 

    c2: single_clock_ram 
    port map (
     clock   => clock_i, 
     we   => we_w, 
     read_address => read_add, 
     write_address => wr_addr, 
     data   => random_num_i, 
     q    => q_out 
    ); 

end architecture rtl; 

Примечания там было random_num STD_LOGIC_VECTOR объявлено подключить к выходу случайных, который преобразуется целое random_num_i, используемое в качестве входных данных для single_clock_ram данных. Выход q из single_clock_ram выглядит немного подозрительным, должен ли быть целым или более широким std_logic_vector?

+0

Спасибо, ребята, за помощь, @ user1155120. Моя цель - создать верхний уровень для двух сущностей random и single_clock_ram. Таким образом, я пытаюсь подключить вывод случайного к блоку ram. Основываясь на ваших комментариях, я изменил свой код, но у меня все еще такая же ошибка. – Kooss

+0

Еще один вопрос, как сделать std_vector и integer с равной длиной? – Kooss

1

Во-первых, удалите нестандартные библиотеки.

use IEEE.std_logic_signed.all; 
use IEEE.std_logic_unsigned.all; 
use IEEE.STD_LOGIC_ARITH.ALL; 

оставив только std_logic_1164 и numeric_std.

Другие представляют собой совокупность перекрывающихся деклараций, из-за чего трудно определить, что происходит - и если имеется несколько объявлений для одного и того же оператора с теми же аргументами и типами результатов, компилятор делает их невидимыми, а не собирает произвольный.


Затем решите, что вы пытаетесь сделать. В настоящее время это неоднозначно и противоречиво.

(1) У вас есть декларативный generic (width : integer :=32); и порт

random_num : out std_logic_vector (width-1 downto 0) 

, которые предполагают, что вы имеете дело с 32-битными словами.

(2) У вас есть колебались целое число: Signal random_num_i: INTEGER RANGE 0 to 31;, который (а) должен быть дальняя NATURAL, чтобы сделать его еще более ясным, что отрицательные значения ошибки, и (б) предполагает, что вы имеете дело с 5-битовых слов.

Что это? Что именно ты пытаешься сделать?

А тут, по-видимому, пытаясь соединить их вместе в карте порта ...

C1: random Port map ( 
    clk => clock_i, 
    --random_num <=to_integer(to_signed(random_num_i)) 
    random_num =>random_num_i 
); 
random_num <=to_integer(to_signed(random_num_i)); -- error 

Есть ряд вещей, которые здесь не так.

1) Для простого сопоставления портов, такого как random_num =>random_num_i, требуется, чтобы обе стороны имели один и тот же тип. Это будет работать, если обе стороны были на самом деле тот же тип: например, если вы добавили объявление сигнала

random_num_slv : std_logic_vector (width-1 downto 0); 

то отображение портов random_num =>random_num_slv будет работать. Теперь вы можете преобразовать в нужный тип random_num_i в назначении сигнала.

random_num_i <= to_integer (unsigned(random_num_slv)); 

Есть еще проблемы с этим: 32-разрядный выход, вероятно, переполнит 5-разрядное целое число.

При добавлении промежуточного сигнала random_num_slv может выглядеть неэффективным и избыточным, он сохраняет дизайн в чистоте и простоте, что имеет значение при работе с инструментами, которые не понимают преобразования типов в портах.

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

(2) Закомментированного картирование порта

random_num <=to_integer(to_signed(random_num_i)) 

бы способ сделать это, за три вещи, за исключением ... (а) <= является назначение сигнала, необходимо => оператор объединения (b) вы преобразовываете целое число в целое число и управляете std_logic_vector с ним. Это действительно не сработает ... (c) порт компонента - OUTPUT, поэтому вы не должны водить его в первую очередь.

То, что вы, вероятно, имел в виду

to_integer(unsigned(random_num)) => random_num_i 

, и это будет самым чистым способом сделать это, если ваши преобразования инструментов поддержки в порту карты правильно. Примечания:

  • снова имеет проблему переполнения, 32-разрядный вектор не будет соответствовать 5-битовому целому числу.
  • Вы можете конвертировать из std_logic_vector в подписанный или неподписанный путем литья unsigned, а не для функции преобразования to_signed, поскольку они являются близкими типами. Целые числа не являются «тесно связанными» с ними, поэтому нужна функция преобразования to_integer.
  • В качестве отрицательных чисел не допускаются декларация random_num_i, используйте unsigned, а не signed.

(3) Существующий назначение сигнала

random_num <=to_integer(to_signed(random_num_i)); -- error 

снова содержит несколько ошибок. Самым большим является то, что нет порта random_num, видимого вне декларации компонента. Просто удалите эту строку, вам нужно использовать одно из сопоставлений портов.


Дальнейшие соображения:

(1) Некоторые преобразования типов неизбежны. Но если вы делаете слишком много, это, как правило, указывает на ошибку дизайна, например, на использование std_logic_vector везде, даже для thengs, таких как адреса, которые неизбежно целые без знака, поэтому unsigned или natural - лучший выбор. Держите дизайн максимально простым и понятным. Я думаю, что ваше использование integer здесь, как правило, хорошо, но natural бы лучше

(2) Если вы хотите добавить гибкость родового как width, использовать его правильно и последовательно (если вы не нужны отрицательные адреса!) - ИЛИ - проверьте, что это действительно.

Здесь, как описано выше, ваш дизайн ТОЛЬКО работает правильно без сюрпризов, ЕСЛИ этот объект создается с помощью width => 5.

Итак, проверьте это значение и прервите, если это условие не выполнено.

assert Width = 5 report "Width of " & natural'image(width) & " not supported!" 
    severity FAILURE; 

ИЛИ сделать проектные работы для всех разумных значений родового, например, делая другие величины зависят от него в действительных отношениях.Например:

constant DEPTH : natural := 2**WIDTH - 1; 
    signal random_num_i : natural range 0 to DEPTH; 

и так далее ...

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