Защо не получавам изход при моя VHDL умножител?

Опитвам се да направя 4-битов умножител. Ето моят дизайн от най-високо ниво: въведете описание на изображението тук

А ето и двата модула: въведете описание на изображението туквъведете описание на изображението тук

Въпреки това, когато се опитвам да симулирам това, не получавам резултат. Моят тестов стенд:

    ARCHITECTURE behavior OF sim3 IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT multiplicator
    PORT(
         a : IN  std_logic_vector(3 downto 0);
         b : IN  std_logic_vector(3 downto 0);
         reset : IN  std_logic;
         clk : IN  std_logic;
         start : IN  std_logic;
         prod : OUT  std_logic_vector(7 downto 0);
         ready : OUT  std_logic
        );
    END COMPONENT;


   --Inputs
   signal a : std_logic_vector(3 downto 0) := (others => '0');
   signal b : std_logic_vector(3 downto 0) := (others => '0');
   signal reset : std_logic := '0';
   signal clk : std_logic := '0';
   signal start : std_logic := '0';

    --Outputs
   signal prod : std_logic_vector(7 downto 0);
   signal ready : std_logic;

   -- Clock period definitions
   constant clk_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: multiplicator PORT MAP (
          a => a,
          b => b,
          reset => reset,
          clk => clk,
          start => start,
          prod => prod,
          ready => ready
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
        wait for clk_period;
        reset<='1';
        wait for clk_period;
        reset<='0';
        a<="0011";
        b<="0010";
        start <='1';
        wait for clk_period*10;
   end process;

END;

Когато настройвам старта на '1', симулацията просто спира. Не знам защо. Получавам следната грешка:

ERROR: at 20 ns(10000): Iteration limit 10000 is reached. Possible zero delay oscillation detected where simulation can not advance in time because signals can not resolve to a stable value in File "D:/faculta/PL II/multiplicator/reg8.vhd" Line 45. Please correct this code in order to advance past the current simulation time.

въведете описание на изображението тук

Не виждам какво може да не е наред в този ред:

q_s <= "00000000" WHEN reset='1' ELSE d WHEN reset='0' and load='1' ELSE q_s;

Малко помощ, моля?


person gdany    schedule 21.05.2015    source източник
comment
Грешката възниква във вашия reg8 обект. Би било полезно да можете да видите този код; единственият ред, който публикувахте, не е достатъчен, за да видим къде е цикълът.   -  person scary_jeff    schedule 21.05.2015


Отговори (1)


Не използвайте регистър с възможност за натоварване, използвайте регистър на часовника. Лимитът на итерация е лимит на делта цикъл в ISIM. Въвеждането на '1' в b вие получавате поразителен осцилатор, цикъл със закъснения на делта цикъла и инверсия (сумирането). Направете num4, reg4 и reg8 край на часовника, задвижван с техните натоварвания като позволява, това изглежда съвместимо с Lab10, който показва използването на часовник (и VHDL източника за @scary_jeff, макар и изразен в тип BIT вместо std_logic). Този феномен на обратната връзка е споменат в книгата на Уилям Кафиг VHDL 101 Всичко, което трябва да знаете, за да започнете, в глава 4.

Google Translate помага. Изглежда никой никога не предоставя своите листовки за техните задачи.

Ако погледнете оригиналното изпълнение на присвояване на q_s в reg4:

block1: 
    block (ck = '1' and not ck'stable)
    begin
        q_s <= guarded "0000" when reset = '1' else
                           d  when reset = '0' and load = '1' else
                         q_s;
    end block block1;

Бих превел това в изявление за процес, което може да се синтезира, вместо в изявление за блок, като изясня, че reg4reg8) е регистър с тактова честота:

block1: 
    process (ck)
    begin
        if rising_edge(ck) then 
            if reset = '1' then
                q_s <= (others => '0');
            elsif load = '1' then
                q_s <= d;
            end if;
        end if;
    end process;

Причината, поради която оригиналът работи, е, че блоковият оператор може да има защитен оператор.

Промяната изяснява, че q_s е тактов регистър със синхронно нулиране.

Можете също така да забележите, че вече не препращаме към q_s и можем да присвоим q директно.

В контролната държавна машина процесът, присвояващ next_state на current_state, също може да бъде актуализиран:

    process (ck)
    begin
        if ck'event and ck = '1' then  -- or rising_edge(ck)
            current_state <= next_state;
        end if;
    end process;

Просто за четливост. Необичайно е да използвате формуляра not ck'stable за обозначаване на часовниково събитие, отбелязвайки, че също така изглежда сте пропуснали значението при прилагането на reg8, потенциално и в reg4 и automat.

Допустимостта на синтеза на защитен израз като часовник, чувствителен към границите, е демонстрирана в IEEE Std 1076.6-2004, 6.1.3.6 Чувствително към граници съхранение с използване на защитен блок.

person Community    schedule 21.05.2015
comment
Това е един случай на по-общо правило: Асинхронната последователна логика трябва да се избягва. Всеки, който е достатъчно експерт, за да има шанс да го накара да работи, също разбира защо е толкова рядко подходящ. - person Ben Voigt; 22.05.2015
comment
@BenVoigt – След като разгледах проблема в дълбочина, бих си представил, че проблемът идва от „попълване на празните места“, създавайки reg8, който не е показан в лабораторната задача, поради неразбиране на използването на защитно изявление, което предполага чувствителен към ръба регистрирам. Успешно дублирах присвояването с помощта на std_logic; - person ; 22.05.2015
comment
Благодаря ти Дейвид! Най-накрая го накарах да работи и сега имам добра симулация. Проблемът беше, че всъщност не разбирах какво правят часовниковите сигнали. Това е много хубаво обяснение и часовникът вече е добър. Работи добре. - person gdany; 22.05.2015
comment
Накарах го също да работи, въпреки че използвах блоково изявление вместо отделен обект/архитектура на caledate. Видях вашия симптом и в num4. Имаше грешка в транскрипцията. Трябва да има само един reg8, prod може да се захранва от акумулатора. - person ; 22.05.2015