Я пишу код VHDL для потокового шифра Salsa20. Его основная функция - это «четвертьраунд», который я успешно написал. Я хочу протестировать его в Modelsim, прежде чем двигаться дальше, но у меня возникают трудности. Я понимаю, что мне нужно «стимулировать» входы, чтобы наблюдать за выходами. Все попытки, которые я предпринял, привели к тому, что результат z не дал никаких значений. Код для Quarterround (верхнего уровня):

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

ENTITY quarter_round is 
    GENERIC(l:integer:=9);
    PORT(y : in unsigned(127 downto 0);
    z : out unsigned( 127 downto 0)
    );
END quarter_round;

ARCHITECTURE quarter_round_arch of quarter_round is

COMPONENT left is                                               
    GENERIC(l:integer);                                     
    PORT( a: in unsigned( 31 downto 0);
    b: out unsigned( 31 downto 0));
    end COMPONENT;
    signal i1,i2,i3,i4 :unsigned( 31 downto 0);
    signal j1,j2,j3,j4 :unsigned( 31 downto 0);
    signal z0,z1,z2,z3 :unsigned( 31 downto 0);
    signal y0 : unsigned( 31 downto 0);                 
    signal y1 : unsigned( 31 downto 0);                 
    signal y2 : unsigned( 31 downto 0);
    signal y3 : unsigned( 31 downto 0);

BEGIN                                                                   
    y0 <=y(127 downto 96);                                  
    y1 <=y(95 downto 64);                                   
    y2 <=y(63 downto 32);
    y3 <=y(31 downto 0);
    i1<=y0+y3;
    a1:left generic map(7) port map(i1,j1);         
    z1<=j1 xor y1;                                              
    i2<=z1+y0;
    a2:left generic map(9) port map(i2,j2); 
    z2<=j2 xor y2;
    i3<=z2+z1;
    a3:left generic map(13) port map(i3,j3);
    z3<=j3 xor y3;
    i4<=z3+z2;
    a4:left generic map(18) port map(i4,j4);
    z0<=j4 xor y0;
    z<=z0&z1&z2&z3;
END quarter_round_arch;

В КОМПОНЕНТЕ осталось:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

ENTITY left is
GENERIC (l:integer:=7);
PORT( n: in unsigned( 31 downto 0);
m: out unsigned( 31 downto 0));
END left;

ARCHITECTURE dataflow of left is
    begin
    m<=n(31-l downto 0)& n(31 downto 31-l+1);
END dataflow;

Стенду, который я пытаюсь написать, будет присвоено значение y (128 бит), обработать функцию, и z должен вывести правильный ответ в Modelsim. Я понимаю, что это базовый вопрос VHDL, но он сводит меня с ума!

Этот код не работает в Modelsim:

LIBRARY ieee;                                               
USE ieee.std_logic_1164.all;                                
USE ieee.numeric_std.all;

ENTITY quarter_round_vhd_tst IS
END quarter_round_vhd_tst;

ARCHITECTURE test of quarter_round_vhd_tst IS

COMPONENT quarter_round
PORT (
    y : IN STD_LOGIC_VECTOR(127 DOWNTO 0);
    z : OUT STD_LOGIC_VECTOR(127 DOWNTO 0)
    );
    END COMPONENT;
    SIGNAL clk : std_logic := '0';
    SIGNAL reset : std_logic := '0';                                       
    SIGNAL y : STD_LOGIC_VECTOR(127 DOWNTO 0);
    SIGNAL z : STD_LOGIC_VECTOR(127 DOWNTO 0);                               
    BEGIN
   DUT : quarter_round
    PORT MAP (
    y => y,
    z => z
    );

    y  <= x"201f1e1d1c1b1a191817161514131211"; 

PROCESS
BEGIN
    clk <= '0' ;
    wait for 10 ns;
    z <= y ;
    clk <= '1';
    wait for 10 ns;
    END PROCESS;
    END test;

Изменить: это последняя попытка. Код компилируется, но Modelsim выдает ошибки, говоря, что типы не совпадают. Любые идеи приветствуются. CT

0
Chaz Tortoise 12 Май 2014 в 05:05

2 ответа

Лучший ответ

david_koontz @ Macbook: ghdl -a Quarter_round.vhdl
david_koontz @ Macbook: ghdl -e квартал_round_vhd_tst
Quarter_round.vhdl: 100: 1: тип сигнального интерфейса "y" от компонента "Quarter_round" и порт "y" от объекта "Quarter_round" не являются совместимый для ассоциации Quarter_round.vhdl: 100: 1: тип сигнальный интерфейс "z" от компонента "Quarter_round" и порт "z" от объект "Quarter_round" несовместим с ассоциацией ghdl: ошибка компиляции

Итак, проблема, которую вы описываете после редактирования, обнаруживается во время проработки. Обратите внимание на то, что тип в объявлении компонента и объект Quarter_round не совпадают.

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

entity quarter_round_vhd_tst is
end quarter_round_vhd_tst;

architecture test of quarter_round_vhd_tst is

    component quarter_round
        port (
            y: in  unsigned(127 downto 0);
            z: out unsigned(127 downto 0)
        );
    end component;

    signal clk : std_logic := '0';
    signal reset : std_logic := '0';
    signal y : unsigned(127 downto 0);
    signal z : unsigned(127 downto 0);
begin
DUT: quarter_round
        port map (
            y => y,
            z => z
        );

CLOCK:
    process
    begin
        wait for 10 ns;    
        clk <= not clk;
        if Now > 30 ns then
            wait;
        end if;
    end process;

STIMULUS:
    process
    begin
        wait for 10 ns;
         y  <= x"201f1e1d1c1b1a191817161514131211";
        wait for 10 ns;
        -- z <= y ;
        wait;  
    end process;
end test;

Изменения касаются отдельного процесса для часов, вероятно, он вам понадобится, когда вы добавите больше. Изначально вы пытались назначить z в тестовой среде, z - это результат четверти_раунд.

Я переместил назначение y в процесс стимулирования. Если используется сброс, вы можете вставить и его туда.

Идея использования операторов ожидания без аргументов состоит в том, чтобы остановить бесконечное повторение процессов. Пока вы назначаете сигналы, они будут идти до Time'HIGH. Сравнение для «Сейчас в процессе» ЧАСЫ может быть изменено на несколько стимулов или на время выполнения. Точно так же вы можете ввести сигнал, используемый для остановки часов, который назначен в процессе (например, STIMULUS), который используется вместо Now, чтобы остановить часы, если что-то выходит из (возможной) модели, что сигнализирует об окончании моделирования.

Если тестируемое устройство не полагается на часы (или сброс), как только y присваивается, z присваивается результат. (Вот почему я поставил задержку перед назначением y, чтобы продемонстрировать это).

Я использовал Quarter_round и оставил, что исправил вчера, поэтому у меня есть a и b вместо m и n.

quarter_round_vhd_test

Итак, результат выглядит правильным?

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

И вы можете использовать преобразование типов в карте портов для четверти раунда:

    signal y : std_logic_vector(127 downto 0);
    signal z : std_logic_vector(127 downto 0);
begin
DUT: quarter_round
        port map (
            y => unsigned(y),
            std_logic_vector(z)=> z
        );

Но объявление компонента по-прежнему должно соответствовать объявлению объекта для Quarter_round.

И если вы уверены, что вам никогда не понадобится настраивать Quarter_round в тестовой среде, вы можете использовать прямое создание экземпляра объекта, исключив объявление компонента:

    -- component quarter_round
    --     port (
    --         y: in  unsigned(127 downto 0);
    --         z: out unsigned(127 downto 0)
    --     );
    -- end component;
    ...

begin
DUT: -- quarter_round
    entity work.quarter_round
        port map (
            y => unsigned(y),
            std_logic_vector(z)=> z
        );

Обычно полезно иметь действительное объявление компонента или, по крайней мере, использовать формальную ассоциацию (вместо позиционной, как показано выше). Таким образом, кто-то, читающий код, не должен считать аргументы, глядя в другое место.

Обратите внимание, что непосредственно созданный экземпляр сущности указан с выбранным именем, указывающим библиотеку, в которой находится сущность.

0
14 Май 2014 в 02:44

Вы, должно быть, не обратили внимания на ошибки компиляции, связанные с "left.vhd". Сигналы «а» и «б» не объявлены.

0
PFA 12 Май 2014 в 19:44