Перейти к содержанию
    

Давайте обговорим создание программируемого коммутатора на VHDL! :)

process (clk, subst_store)
variable i:integer;
begin
    for i in 15 downto 0 loop
        iSubst(i) <= subst_store(i*4+3 downto i*4);
    end loop; 
    if rising_edge(CLK) then
        if (load='0' and start='1') then
            for i in 15 downto 0 loop
                reg_out(i) <= reg(conv_integer(iSUBST(i)));
            end loop;
        elsif (load='1' and start='1') then
            reg_out <= reg;
        end if;
    end if;
end process;

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ребята! Погодьте! вы уже несколько от темы ушли! :)

Как я уже говорил, следующий код на симуляторе выдает лажу, а именно:

при заданной подстановке, к примеру:

1234

3241

у меня выходит:

1234

1423 , т.е. как будто биты записаны в обратном порядке.

 

Изменение порядка загрузки битов в регистр, почему-то ни к чему не приводит...

 

Вот код.

Пожалуйста, проверьте его.

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 Mux2x32 is
    Port (
      K : in  std_logic_vector (3 downto 0);
      clk : in  STD_LOGIC;
      rst : in STD_LOGIC;
      S_in : in std_logic;
      reg_out : out  std_logic_vector (15 downto 0);
      start : in  STD_LOGIC;
        reg_in: out std_logic_vector (15 downto 0);
        subst_out : out std_logic_vector (63 downto 0);
      load : in  STD_LOGIC);
end Mux2x32;

architecture Behavioral of Mux2x32 is
   signal subst_store : std_logic_vector (63 downto 0);
   signal reg : std_logic_vector (15 downto 0);
   subtype tIndex is std_logic_vector (3 downto 0);
   type tSUBST is array(15 downto 0) of tIndex;
   signal iSUBST   : tSUBST;
begin

process (clk)
variable i:integer;
begin

if rising_edge(CLK) then
  --Reset
  if rst='1' then
    for i in 0 to 15 loop
      iSUBST(i) <= (others => '0');
    end loop;
     reg_out<=(others => '0');
     reg_in<=(others => '0');
     subst_store<=(others => '0');
  --Load register and Kommutator
  elsif (load='1' and start='0') then
    subst_store<=subst_store(59 downto 0) & K;
    reg<=reg(14 downto 0) & S_in;
  --Substitution
  elsif (load='0' and start='1') then
    for i in 15 downto 0 loop
      reg_out(i) <= reg(conv_integer(iSUBST(i)));
    end loop;
     reg_in<=reg;
     subst_out<=subst_store;
  --other states
  elsif ((load='1' and start='1') or (load='0' and start='0')) then
            for i in 15 downto 0 loop
                iSubst(i)<=subst_store(i*4+3 downto i*4);
            end loop;

  end if;  
end if;  

end process;

end Behavioral;

 

Я вывел парочку разъемов, чтоб симуляция покрыла большинство состояний....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ребята! Погодьте! вы уже несколько от темы ушли! :)

Как я уже говорил, следующий код на симуляторе выдает лажу, а именно:

при заданной подстановке, к примеру:

1234

3241

у меня выходит:

1234

1423 , т.е. как будто биты записаны в обратном порядке.

 

Изменение порядка загрузки битов в регистр, почему-то ни к чему не приводит...

 

Вот код.

Пожалуйста, проверьте его.

 

... У меня в подвале стук. Не волнуйтесь - это глюк ...

Приведите пример Вашего тестбенча и ожидаемых в результате его работы значений. Без этого все вопросы по поводу работы Вашего модуля не имеют достаточных исходных данных для обсуждения. Будет тестбенч - будет ответ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извините, вот оно все... :)

 

reg(i) <= reg(conv_integer(iSUBST(i)));

надо поменять на

reg_out(i) <= reg(conv_integer(iSUBST(i)));

 

Забыл поменять. Но сути вопроса это не меняет...!!!!

Podstava.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извините, вот оно все... :)

 

reg(i) <= reg(conv_integer(iSUBST(i)));

надо поменять на

reg_out(i) <= reg(conv_integer(iSUBST(i)));

 

Забыл поменять. Но сути вопроса это не меняет...!!!!

 

Кто Вас так учил писать тестбенчи? Если схема синхронная, то задавать значения сигналов нужно не с абстрактным шагом (пусть даже и правильным), а в привязке к синхросигналу (CLK). Т.е. тело основного процесса Вашего тестбенча должно выглядеть приблизительно так:

        wait until rising_edge(CLK);
        rst <= '1';
        K <= "0001";
        wait until rising_edge(CLK);
        load <= '1';
        rst <= '0';
        K <= "0000";
        wait until rising_edge(CLK);
        S_in <= '1';
        K <= "0001";
        wait until rising_edge(CLK);
        S_in <= '0';
        K <= "0100";
        wait until rising_edge(CLK);
        K <= "0011";
        wait until rising_edge(CLK);
        S_in <= '1';
        K <= "0010";
        wait until rising_edge(CLK);
        K <= "0101";
        wait until rising_edge(CLK);
        K <= "1011";
        wait until rising_edge(CLK);
        S_in <= '0';
        K <= "0111";
        wait until rising_edge(CLK);
        S_in <= '1';
        K <= "1000";
        wait until rising_edge(CLK);
        S_in <= '0';
        K <= "1110";
        wait until rising_edge(CLK);
        K <= "1010";
        wait until rising_edge(CLK);
        K <= "0110";
        wait until rising_edge(CLK);
        S_in <= '1';
        K <= "1100";
        wait until rising_edge(CLK);
        S_in <= '0';
        K <= "1101";
        wait until rising_edge(CLK);
        S_in <= '1';
        K <= "1001";
        wait until rising_edge(CLK);
        S_in <= '0';
        K <= "1111";
        wait until rising_edge(CLK);
        load <= '0';
        wait until rising_edge(CLK);
        start <= '1';

 

В противном случае возможны ситуации, когда входные сигналы могут восприниматься модулем некорректно. Вот что получается в результате моделирования:

post-904-1217251407_thumb.jpg

 

 

При моделировании я использовал модуль, приведенный мною ранее (не из Вашего архива, т.к. Вы его порядком исказили в процессе отладки): Mux2x32.vhd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вся эта краснота с неопределенностью не от некорректного тестбенча, а от неполного описания действий по сигналу rst.

Неужели никто в rtl просмотрщик не смотрит. Ведь порождается триггер с enable, на который rst подается. И нет никакого ресета для симулятора.

Простейшая структура. Регистр - мультиплексор - регистр.

Да кто VHDL то придумал. Злюки-преподаватели наверно.

Чтобы студентов мучить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вся эта краснота с неопределенностью не от некорректного тестбенча, а от неполного описания действий по сигналу rst.

Неужели никто в rtl просмотрщик не смотрит. Ведь порождается триггер с enable, на который rst подается. И нет никакого ресета для симулятора.

 

Триггер порождается, безусловно, с Enable, вот только насчет RST Вы совсем не правы. RST подается на вход R регистра, т.е. как и должно быть. Это обусловлено тем, что он имеет наивысший приоритет. Пример RTL, подтверждающий мои слова (вышеприведенный модуль Mux2x32, ISE 10.1i SP2):

post-904-1217253703_thumb.jpg

 

Простейшая структура. Регистр - мультиплексор - регистр.

Да, и то столько возникает проблем. Но дело не в VHDL. См. выше.

 

Да кто VHDL то придумал. Злюки-преподаватели наверно.

Чтобы студентов мучить.

 

О вкусах не спорят. Меня этот язык пока устраивает больше, чем чистый Verilog. Но это мое личное мнение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Короче, разобрался. Пользуйтесь! :)

Все нормально.

Вот код.

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    09:18:27 07/28/2008 
-- Design Name: 
-- Module Name:    mux16 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.Std_logic_arith.all;
USE IEEE.NUMERIC_STD.ALL;

entity Mux2x32 is
    Port (
      K : in  std_logic_vector (3 downto 0);
      clk : in  STD_LOGIC;
      rst : in STD_LOGIC;
      S_in : in std_logic;
      reg_out : out  std_logic_vector (15 downto 0);
      start : in  STD_LOGIC;
        reg_in: out std_logic_vector (15 downto 0);
        subst_out : out std_logic_vector (63 downto 0);
      load : in  STD_LOGIC);
end Mux2x32;

architecture Behavioral of Mux2x32 is
   signal subst_store : std_logic_vector (63 downto 0);
   signal reg : std_logic_vector (15 downto 0);
   subtype tIndex is std_logic_vector (3 downto 0);
    type tSUBST is array(15 downto 0) of tIndex;
   signal iSubst   : tSUBST;
begin

process (clk)
variable i:integer;
begin

if rising_edge(CLK) then
  --Reset
  if rst='1' then
    for i in 0 to 15 loop
      iSubst(i) <= (others => '0');
    end loop;
     reg_out<=(others => '0');
     reg_in<=(others => '0');
     subst_store<=(others => '0');
  --Load register and Kommutator
  elsif (load='1' and start='0') then
    subst_store<=subst_store(59 downto 0) & K;
    reg<=reg(14 downto 0) & S_in;
  --Substitution
  elsif (load='0' and start='1') then
    for i in 15 downto 0 loop
        reg_out(conv_integer(iSubst(i))) <= reg(i);
    end loop;
     reg_in<=reg;
     subst_out<=subst_store;
  --other states
  elsif ((load='1' and start='1') or (load='0' and start='0')) then
            for i in 15 downto 0 loop
                iSubst(i)<=subst_store(i*4+3 downto i*4);
            end loop;

  end if;  
end if;  

end process;

end Behavioral;

Все дело в том, что с самого начала применил не прямую, а инвалютивную :) подстановку. Т.е. обратную.

Надо было в моем коде переписать строку

reg_out(i) <= reg(conv_integer(iSubst(i)));

на

reg_out(conv_integer(iSubst(i))) <= reg(i);

 

Все. всем спасибо!

Если что, пишите: [email protected]

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Триггер порождается, безусловно, с Enable, вот только насчет RST Вы совсем не правы. RST подается на вход R регистра, т.е. как и должно быть.

 

Согласно описанию, процесс только по фронту клока. О каком асинхронном ресете может идти речь.

Должно быть мультиплексирование по входу регистра для синхронного ресета. (Хотя допускаю, что это примитив xilinx с синхронным ресетом)

Квартус породил dffe без входа R.

Если xst увидел при некорректном описании вход R - сочувствую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно описанию, процесс только по фронту клока. О каком асинхронном ресете может идти речь.

 

Я разве где-то сказал, что ресет будет асинхронный? Нет, согласно описанию, ресет будет синхронный.

Согласно условным обозначениям примитивов ПЛИС Xilinx R - обозначает синхронный ресет, а CLR - асинхронный. На картинке в моем сообщении выше Вы можете наблюдать вход R у регистра reg_out.

 

Должно быть мультиплексирование по входу регистра для синхронного ресета. (Хотя допускаю, что это примитив xilinx с синхронным ресетом)

 

Да, именно сихнронный сброс.

 

Квартус породил dffe без входа R.

Если xst увидел при некорректном описании вход R - сочувствую.

 

Если в библиотеке примитивов у Альтеры есть триггеры с синхронным сбросом/установкой, то сочувствовать нужно пользователям квартуса, т.к. налицо проблемы с оптимизацией. Кстати говоря, у Xilinx в руководстве "Synthesis and Simulation Design Guide" приведен пример описания триггера с синронной установкой (для сброса - аналогично):

Flip-Flop with Positive Edge Clock and Synchronous Set VHDL Coding Example
process (C)
begin
    if (C'event and C='1') then
        if (S='1') then
            Q <= '1';
        else
            Q <= D;
        end if;
    end if;
end process;

 

Этот пример подверждает правильность работы XST и сделанного выше описания.

 

PS: Вот еще один пример, подтверждающий мои слова (источник - http://en.wikipedia.org/wiki/VHDL):

 

-- template for synchronous reset with clock enable:
process(CLK)
begin
    if rising_edge(CLK) then
        if RESET = '1' then 
            Q <= '0';
        elsif Enable = '1' then  -- or '0' if Enable is active low...
            Q <= D;
        end if;
    end if;
end process;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Этот пример подверждает правильность работы XST и сделанного выше описания.

 

Я не буду спорить. Я увидел реакцию моделсима и сделал соответствующий вывод.

Не может быть покрасневшей неопределенности на промежуточных регистрах в течении больше чем один период клока при синхронной установки данных.

Ресурсы - это уже совсем другое.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не буду спорить. Я увидел реакцию моделсима и сделал соответствующий вывод.

 

В одной и той же картинке два человека могут увидеть совершенно разное.

Тем не менее, на приведенной мною иллюстрации, как и описано в модуле, в сброшенном состоянии находятся только reg_out и isubst. Другие сигналы, находятся в неопределенном состоянии до момента записи в их соответствующие разряды поскольку для них не определен сигнал синхронного сброса. Поэтому я считаю, что Вы сделали неправильный вывод.

 

Не может быть покрасневшей неопределенности на промежуточных регистрах в течении больше чем один период клока при синхронной установки данных.

 

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

 

Ресурсы - это уже совсем другое.

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

 

Я правильно понимаю, что для Вас Квартус - непогрешимая истина и идеал синтезатора? Я о том, что если ресурсов для реализации синхронного ресета нет, то он его пытается эмулировать с помощью мультиплексора по входу данных и соответствующего сигнала разрешения записи. Но если у примитивов триггеров синхронный ресет есть... Тогда такая реализация не очень хороший вариант. В любом случае, если мы говорим про RTL - реализация имеет значение.

Вы приведенные мною ссылки и примеры читали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я правильно понимаю, что для Вас Квартус - непогрешимая истина и идеал синтезатора?Тогда такая реализация не очень хороший вариант. В любом случае, если мы говорим про RTL - реализация имеет значение.

Вы приведенные мною ссылки и примеры читали?

 

Мне все равно на чем и как. Я начинал со xilinx.

Вот еще раз пересмотрел (Надо за один такт переставить все значения в регистре на 16 по адресам в коммутаторе. )

За ссылки спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...