VHDL. Почему мое значение rdy не меняется на 1? Все еще в замешательстве

На моей диаграмме формы сигнала мне интересно, почему мое значение «rdy» не меняется на 1 после 400 нс. И почему мое значение «d» ничего не выводит после первых двух выходов? Я пытался найти ошибку в течение нескольких часов, но безрезультатно. Пожалуйста, помогите, заранее спасибо.

Вот моя диаграмма формы волны:

диаграмма сигнала

И вот мой основной код.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity GCD is
port(st , clk: in std_logic;        --clk temporarily taken out
     d1, d2 : in std_logic_vector(7 downto 0);
     dout : out std_logic_vector(7 downto 0);
     rdy : out std_logic);
end GCD;

architecture behav of GCD is
type state is (S0, S1, S2, S3, S4, S5, S6, S7);

--temporary clk
--signal clk : std_logic;

signal new_state : state;
signal eq : boolean;
signal eq1 : boolean;
signal lt : boolean;

begin
    --State transition
    process is
    variable curr_state : state:= S0;
    begin
        if clk = '1' then
        case curr_state is
            when S0 => 
                if st = '1' then curr_state := S1;
                end if;
            when S1 =>
                curr_state := S2;
            when S2 =>
                if eq and not lt then curr_state := S7;
                elsif lt and not eq then curr_state := S4;
                elsif not eq and not lt then curr_state := S3;
                end if;
            when S3 => 
                curr_state := S4;
            when S4 =>
                curr_state := S5;
           when S5 =>
                if eq1 = true then curr_state := S7;
                else curr_state := S6;
                end if;
            when S6 =>
                curr_state := S1;
            when S7 =>
                if st = '0' then curr_state := S0;
                end if;
        end case;
        new_state <= curr_state;
        end if;
        wait on clk;
    end process;


--Asserted Output Process
process is
variable M, N, dout_val, tmp: std_logic_vector(7 downto 0);
variable rdy_val : std_logic;
variable lt_val, eq_val, eq1_val : boolean;
begin
    rdy_val := '0';
    case new_state is

        when S0 =>
            M :=  d1;
            N := d2;
        when S1 =>
            if (to_integer(M) = to_integer(N)) then eq_val := true;
            elsif (to_integer(M) < to_integer(N)) then lt_val := true;
            end if;

        when S2 =>
        when S3 =>
            M := N;
            N := M;         
        when S4 =>
            if (to_integer(M) = 1) then eq1_val := true;
            end if;
        when S5 =>
        when S6 =>
            N := (N - M);
        when S7 =>
            rdy_val := '1';
            dout_val := M; 
    end case;
    dout <= dout_val;   
    rdy <= rdy_val;
    lt <= lt_val;
    eq <= eq_val;
    eq1 <= eq1_val;
    wait on new_state;
end process;
end behav;

А вот и мой тестовый стенд:

library IEEE;

use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

use work.all;

entity test_GCD is
end test_GCD;

architecture testbench of test_GCD is
signal m, n ,d: std_logic_vector(7 downto 0);
signal clk, st, rdy : std_logic;

begin

    --Component Instantiation
    device : GCD
    port map( clk => clk, st => st, d1 => m, 
              d2 => n, dout => d, rdy => rdy);


    --Process to Generate Test Data
    process is
    begin
        st <= '0';
        wait for 10ns;
        m <= "00001001";    --9 , 15    
        n <= "00001111";
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "00001111";    --15, 9
        n <= "00001001";        
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;      --15 , 14
        m <= "00001111";
        n <= "00001110";
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "00010010";    --18 , 36
        n <= "00100100";
        wait for 30ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "01011011";    --91 = 01011011 , 39 = 00100111
        n <= "00100111";
        wait for 10ns;
        st <= '1';
        --wait for 10ns;
        wait until rdy = '1';
        wait for 10ns;

        st <= '0';
        wait for 10ns;
        m <= "01111111";    --127, 127
        n <= "01111111";
        wait for 10ns;
        st <= '1';
        wait until rdy = '1';
        wait for 10ns;

        wait;
    end process;

process is
begin
    clk <= '0', '1' after 15ns;
    wait for 30ns;
end process;

end testbench;

person Brandy Au    schedule 27.09.2014    source источник
comment
Из любопытства, какой инструмент VHDL вы используете, который не требует пробела между числовым литералом и единицей (например, 10 нс)? Также не требуется объявление компонента для GCD, и у вас нет предложения использования для пакета synopsys std_logic_unsigned (или numeric_std_unsigned).   -  person    schedule 27.09.2014
comment
Я использую DesignWorks 5 от Capilano Computing.   -  person Brandy Au    schedule 27.09.2014
comment
Ваш DesignWorks не является строго совместимым со стандартом VHDL по трем причинам, продемонстрированным в вашем коде.   -  person    schedule 28.09.2014


Ответы (1)


Вы второй, кто сегодня задает здесь вопрос с таким же заданием.

В третьем сете st/rdy вы нарушили соотношение времени:

    st <= '0';
    wait for 10ns;
    m <= "00010010";    --18 , 36
    n <= "00100100";
    wait for 30ns;
    st <= '1';
    wait until rdy = '1';
    wait for 10ns;

Предыдущие два набора имеют ожидание 10 нс. Этот имеет 30 нс. Что это делает?

Вы являетесь конечным автоматом в немаркированном процессе перехода состояния, в котором отсутствует st ‹= '1', потому что он не ищет его, когда это происходит, добавьте сигналы в GCD, попробуйте new_state.

Существует прекрасный баланс между помощью кому-то и выполнением его задания за него.


дополнение

Можете ли вы пояснить, что вы имеете в виду, говоря, что я пропускаю st‹='1' при переходе между состояниями? Я объявил st как std_logic, поэтому не могу использовать для него присваивание "‹=". Вы имеете в виду, что мне не хватает st‹='1' в моем тестовом стенде?

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

Ваш конечный автомат работает на положительном фронте тактовых импульсов, даже если ваш код написан так, чтобы его нельзя было синтезировать. Процесс управляется только одним событием, clk, и выражение clk = '1'вычисляется в первом условии оператора if.

если вы добавите new_state в дамп сигнала (покажите его на дисплее сигнала):

test_GCD_ghw.png (картинку можно открыть в отдельной вкладке или окне, это ссылка на себя)

(И обратите внимание, что первый «ответ» НОД состоит из U. Второй «ответ» также не является наибольшим общим знаменателем между 15 и 9.)

Вы увидите, что ваш конечный автомат прекращает переход, оставаясь застрявшим в S2, который оценивает lt и eq, но не изменяет их в процессе утвержденного вывода (и вы можете использовать метки вместо комментариев, любой оператор может быть помечен в VHDL).

Смотрим на предыдущее состояние S1, где назначены eq_val и lt_val. Они зависят от M и N, которые назначаются из d1 и d2 в S0.

Вернемся к уведомлению S2:

        when S2 =>
            if eq and not lt then 
                curr_state := S7;
            elsif lt and not eq then 
                curr_state := S4;
            elsif not eq and not lt then 
                curr_state := S3;
            end if;

И если вы посмотрите на eq и lt на приведенном выше сигнале, вы увидите, что они оба true. Как это может быть? Для этого есть условие перехода, вы вставляете S2.

Так как же оба условия могут быть true одновременно?

    when S1 =>
        if (to_integer(M) = to_integer(N)) then 
            eq_val := true;
        elsif (to_integer(M) < to_integer(N)) then 
            lt_val := true;
        end if;

Вы назначаете только один из них.

Однако другой остается в своем предыдущем состоянии, заблокированном new_state.

В качестве краткой демонстрации я присвоил eq_val и lt_val обоим false прямо перед их оценкой. Это оставит не более одного true.

К сожалению, это показывает еще один недостаток в вашем дизайне:

test_GCD_ghw_only_one_lt_eq.png

И это не предмет вашего вопроса.

Похоже, вы используете алгоритм Euclid (GCD), показанный на блок-схеме (рис. 1) в PDF, найденном по ссылке. Логические типы, по-видимому, являются требованием задания (другой студент также использовал их). Полученный VHDL выражает этот алгоритм по крайней мере еще с одной ошибкой.

Вы используете N в качестве аккумулятора при нахождении НОД, а также изменяете содержимое M. N имеет три источника, d2, результат N-M в S6 and swappingMandNinS3(which has the effect of assigningNtoM, andN` самому себе, присваивание переменной выполняется немедленно). M и N должны быть сигналами, или вам нужно промежуточное значение для переключения. (Они должны быть сигналами).

Вы можете использовать отображение сигнала для устранения неполадок в проекте. Вы также должны знать, когда вы делаете вывод о защелках, которые возникают, когда у вас есть условные присваивания без эквивалента «иначе».

Инструменты с открытым исходным кодом, которые я использовал при просмотре вашего проекта (ghdl и gtkwave), не фиксируют переменные в дампах сигналов. Я подозреваю, что DesignWorks 5 тоже этого не делает (и могу ошибаться). Результатом этого является то, что вы не можете видеть, что данные делают во время моделирования. Ваша конструкция достаточно мала, чтобы вы могли использовать сигналы без значительного влияния на время симуляции. Присвоение eq и lt непосредственно в S1 потребует присвоения else (false). Если вам необходимо использовать переменные для назначения, вы можете назначить их сигналам, чтобы они были видны, если DesignWorks 5 не отображает переменные. Как только вы закончите, вы можете удалить сигналы.

Ответ на вопрос Почему мое значение «rdy» не меняется на 1? заключается в том, что вы определили защелки, создающие случай, который вы не обнаруживаете для ответвления от S2.

Как только вы исправите перестановку M и N в S3, похоже, что это может иметь хорошие шансы или работать (там может быть еще одна ошибка или две).

И когда вы используете tmp для хранения значения M (без использования сигналов):

        when S3 =>
            tmp := M;
            M := N;
            N := tmp;      

Вы начинаете получать правильные ответы:

test_GCD_ghw_using_tmp.png

Не видя раздаточный материал, который вам дали для вашего проекта, я предполагаю, что вы работали с псевдокодом, как показано на рисунке 1 связанного PDF-файла. Возможно, он был написан в ожидании использования сигналов.

person Community    schedule 27.09.2014
comment
Спасибо за ваш ответ Давид. Можете ли вы уточнить, что вы имеете в виду, говоря, что мне не хватает st‹= '1' в переходе между состояниями? Я объявил st как std_logic, поэтому я не могу использовать для него присваивание ‹=. Вы имеете в виду, что мне не хватает st‹='1' в моем тестовом стенде? - person Brandy Au; 27.09.2014
comment
Спасибо, Дэвид. Я прочитал его и, похоже, решил большинство проблем. - person Brandy Au; 28.09.2014