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

Помогите разобраться с case на VHDL

Хочу вместо вложенных условных операторов вида:

if a='1' then

elsif b='1' then

elsif c='1' then

elsid d='1' then

else

........

 

написать:

 

sel(3)<=a;

sel(2)<=b;

sel(1)<=c;

sel(0)<=d;

 

case sel(3 downto 0) is

when 8 to 15 => .........

when 4 to 7 => .........

when 2 to 3 => .........

when 1 => .........

when others => .........

end case;

 

какой тип данных при этом должны иметь: a,b,c,d, и sel?

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


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

Возьмите за основу код (см. ниже) и подправьте под свои нужды.

 

library IEEE;

use IEEE.std_logic_1164.all;

 

entity rdmux16x8 is

port (

EN : in std_logic;

I0 : in std_logic_vector(15 downto 0);

I1 : in std_logic_vector(15 downto 0);

I2 : in std_logic_vector(15 downto 0);

I3 : in std_logic_vector(15 downto 0);

I4 : in std_logic_vector(15 downto 0);

I5 : in std_logic_vector(15 downto 0);

I6 : in std_logic_vector(15 downto 0);

I7 : in std_logic_vector(15 downto 0);

S : in std_logic_vector(2 downto 0);

O : out std_logic_vector(15 downto 0)

);

end entity;

 

--}} End of automatically maintained section

 

library IEEE;

use IEEE.std_logic_unsigned.all;

 

architecture rdmux16x8_arch of rdmux16x8 is

constant NON_ACTIVE : std_logic_vector(15 downto 0) := (others => '0');

 

begin

 

process (S, EN, I0, I1, I2, I3, I4, I5, I6, I7)

begin

if EN = '0' then

O <= NON_ACTIVE;

else

case CONV_INTEGER(S) is

when 0 => O <= I0;

when 1 => O <= I1;

when 2 => O <= I2;

when 3 => O <= I3;

when 4 => O <= I4;

when 5 => O <= I5;

when 6 => O <= I6;

when 7 => O <= I7;

when others => O <= NON_ACTIVE;

end case;

end if;

end process;

 

end rdmux16x8_arch;

 

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


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

Возьмите за основу код (см. ниже) и подправьте под свои нужды.

 

library IEEE;

use IEEE.std_logic_1164.all;

 

entity rdmux16x8 is

port (

EN : in std_logic;

I0 : in std_logic_vector(15 downto 0);

I1 : in std_logic_vector(15 downto 0);

I2 : in std_logic_vector(15 downto 0);

I3 : in std_logic_vector(15 downto 0);

I4 : in std_logic_vector(15 downto 0);

I5 : in std_logic_vector(15 downto 0);

I6 : in std_logic_vector(15 downto 0);

I7 : in std_logic_vector(15 downto 0);

S : in std_logic_vector(2 downto 0);

O : out std_logic_vector(15 downto 0)

);

end entity;

 

--}} End of automatically maintained section

 

library IEEE;

use IEEE.std_logic_unsigned.all;

 

architecture rdmux16x8_arch of rdmux16x8 is

constant NON_ACTIVE : std_logic_vector(15 downto 0) := (others => '0');

 

begin

 

process (S, EN, I0, I1, I2, I3, I4, I5, I6, I7)

begin

if EN = '0' then

O <= NON_ACTIVE;

else

case CONV_INTEGER(S) is

when 0 => O <= I0;

when 1 => O <= I1;

when 2 => O <= I2;

when 3 => O <= I3;

when 4 => O <= I4;

when 5 => O <= I5;

when 6 => O <= I6;

when 7 => O <= I7;

when others => O <= NON_ACTIVE;

end case;

end if;

end process;

 

end rdmux16x8_arch;

 

Ваш код в моем случае не работает.

Есть процесс в котором реализован автомат на if then. В одном из состояний находятся операторы выбра.

if a='1' then

elsif b='1' then

elsif c='1' then

elsif d='1' then

else

Они мне не подходят из-за того, что кушают много логики. Хочу переделать тоже самое с case. Пример моего процесса

 

process(clk)

if (clk'event and clk='1') then

if state="001" then

...................

end if;

 

if state="010" then

...................

end if;

 

if state="011" then

sel(3)<=a;

sel(2)<=b;

sel(1)<=c;

sel(0)<=d;

 

case sel(3 downto 0) is

when 8 to 15 => .........

when 4 to 7 => .........

when 2 to 3 => .........

when 1 => .........

when others => .........

end case;

end if;

..................................

Повторю вопрос. Какой тип данных при этом должны иметь: a,b,c,d, и sel?

 

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


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

2 maxics

Как вариант:

...
signal a : std_logic;
signal b : std_logic;
signal c : std_logic;
signal d : std_logic;

signal sel : std_logic_vector(3 downto 0);
...
sel <= a & b & c & d;
..
case sel is
...
end case;
...

 

Но я бы дополнительно ещё проверил что замена if на case не поломает ничего в логике.

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


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

2 maxics

Как вариант:

...
signal a : std_logic;
signal b : std_logic;
signal c : std_logic;
signal d : std_logic;

signal sel : std_logic_vector(3 downto 0);
...
sel <= a & b & c & d;
..
case sel is
...
end case;
...

 

Но я бы дополнительно ещё проверил что замена if на case не поломает ничего в логике.

 

Так выдает ошибку.

Заработало когда перед Sel поставил conv_integer:

 

signal a : std_logic;

signal b : std_logic;

signal c : std_logic;

signal d : std_logic;

 

signal sel : std_logic_vector(3 downto 0);

...

sel(3)<=a;

sel(2)<=b;

sel(1)<=c;

sel(0)<=d;

 

case (conv_integer(sel(3 downto 0))) is

when 8 to 15 => .........

when 4 to 7 => .........

when 2 to 3 => .........

when 1 => .........

when others => .........

end case;

end if;

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


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

Так выдает ошибку...

Потому что у вас в case десятичные цифры, впишите туда их как для std_logic_vector и conv_integer можно убирать. Хотя судя по приведённому вами листингу, вам может conv_integer в самый раз..

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


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

Потому что у вас в case десятичные цифры, впишите туда их как для std_logic_vector и conv_integer можно убирать. Хотя судя по приведённому вами листингу, вам может conv_integer в самый раз..

 

Вписываю как std_logic_vector . При синтезе ошибка: Choise must be discrete range.

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


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

2 maxics

вот пример

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity test00 is
   Port ( a : in  STD_LOGIC;
          b : in  STD_LOGIC;
          c : in  STD_LOGIC;
          d : in  STD_LOGIC;
          dout : out  STD_LOGIC);
end test00;

architecture rtl of test00 is
signal sel : std_logic_vector(3 downto 0);
begin

sel <= a & b & c & d;

process (sel)
begin
   case sel is
       when "1000" => dout <= '1';
       when "0100" => dout <= '1';
       when "0010" => dout <= '1';
       when "0001" => dout <= '1';
       when others => dout <= '0';
   end case;
end process;

end rtl;

Собирается без вопросов на 1м луте

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


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

2 maxics

вот пример

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity test00 is
   Port ( a : in  STD_LOGIC;
          b : in  STD_LOGIC;
          c : in  STD_LOGIC;
          d : in  STD_LOGIC;
          dout : out  STD_LOGIC);
end test00;

architecture rtl of test00 is
signal sel : std_logic_vector(3 downto 0);
begin

sel <= a & b & c & d;

process (sel)
begin
   case sel is
       when "1000" => dout <= '1';
       when "0100" => dout <= '1';
       when "0010" => dout <= '1';
       when "0001" => dout <= '1';
       when others => dout <= '0';
   end case;
end process;

end rtl;

Собирается без вопросов на 1м луте

 

"a" имеет высший приоритет. Рассмотрим случай a=1 и одновременно c =1. Получаем 1100. И что мы будем делать? others в этом случае не подходит. В моем случае необходимо рассматривать интервалы, т.е. например для первого случая это от 1000 до 11111 (независимо какие b c d делаем определенное действие, т.к. a=1. )

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


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

"a" имеет высший приоритет. Рассмотрим случай a=1 и одновременно c =1. Получаем 1100. И что мы будем делать? others в этом случае не подходит. В моем случае необходимо рассматривать интервалы, т.е. например для первого случая это от 1000 до 11111 (независимо какие b c d делаем определенное действие, т.к. a=1. )

возможно Вам нужен приоритетный шифратор (я по другому не пытался описывать)...

пример:

library IEEE;
use IEEE.std_logic_1164.all;
entity MY_IF is
port (C,D,E,F: in std_logic;
S: in std_logic_vector(1 downto 0);
POUT: out std_logic);
end MY_IF;
architecture MY_IF_ARCH of MY_IF is
begin
process(S,C,D,E,F)
begin
if S=”00” then POUT<=C;
elsif S=”01” then POUT <=D;
elsif S=”10” then POUT <=E;
else POUT <=F;
end if;
end process;
end MY_IF_ARCH;

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


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

возможно Вам нужен приоритетный шифратор (я по другому не пытался описывать)...

пример:

library IEEE;
use IEEE.std_logic_1164.all;
entity MY_IF is
port (C,D,E,F: in std_logic;
S: in std_logic_vector(1 downto 0);
POUT: out std_logic);
end MY_IF;
architecture MY_IF_ARCH of MY_IF is
begin
process(S,C,D,E,F)
begin
if S=”00” then POUT<=C;
elsif S=”01” then POUT <=D;
elsif S=”10” then POUT <=E;
else POUT <=F;
end if;
end process;
end MY_IF_ARCH;

 

Как раз от этого пришлось отказаться из-за большого logic level

 

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


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

2maxics:

Я Вам привел пример своего кода, в котором для оеализации необходимого Вам требования приведена функция conv_integer. Это ключевая подсказка. В понедельник переработаю Ваш код, взяв за основу свой пример. Время терпит?

 

P.S.: "Повторю вопрос. Какой тип данных при этом должны иметь: a,b,c,d, и sel?". объявляете их как std_logic, затем используете conv_integer для дешифрации. Помощь Вам не очевидна?

P.P.S.: Обратное преобразование по моему что-то вроде conv_std_logic_vector (если не ошибаюсь).

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


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

Как раз от этого пришлось отказаться из-за большого logic level

если так, Вам никто не запрещает разбить схему на несколько схем, тогда увеличете скоростные характеристики и уменьшите logic level...

 

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


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

если так, Вам никто не запрещает разбить схему на несколько схем, тогда увеличете скоростные характеристики и уменьшите logic level...

 

Не могли бы пояснить? Желательно на примере. Спасибо!

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


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

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

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

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

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

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

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

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

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

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