Страница 1 из 2
Не могу выразить словами на VHDL
Добавлено: Сб дек 19, 2009 23:29:14
uldemir
Нужен совет впециалиста по VHDL. Вроде как позволяется создавать свои списки. Но мне чего-то не удается сделать это. Допустим, простая задача: хочу сделать счетчик, который проходит следующие состояния: "11", "01", "10". Вот код который я попытался накропать читая учебник, но он не компилируется. Утверждает, что слову 'type' там не место. Конечно присваивание следующего значения - тоже сомниваюсь, что так можно делать. скорее должно быть что-то вроде инкремента переменной индекса массива и затем выбор элемента массива, но и на строчку variable i : integer; - компилятор тоже ругается, что "так можно делать только для SHARE переменных".
Код: Выделить всё
entity counter is
Port(clk in: std_logic;
count out : std_logic_vector);
end counter;
architecture Behavioral of counter is
type thd is ("11", "01","10");
type thd_array is array (integer range <>) of thd;
signal count_signal : std logic_vector (1 downto 0) := thd_array(0);
begin
process(clk)
begin
if clk'event and clk='1' then
count_signal <= count_signal+1;
end if;
end process;
count <= count_signal;
end Behavioral;
Покажите образец как такие вещи писать.
p.s. Таблицы перекодировки, pls, не предлагать. Интересует именно использование выразительных средств языка.
Добавлено: Пн дек 21, 2009 13:44:18
nick17
Port(clk in: std_logic;
count out : std_logic_vector);
________________
укажи для начала разрядность порта count out и без пробелов...Например так:
Port(clk_in: std_logic;
count_out : std_logic_vector(1 downto 0));
Потом посмотрим...
Добавлено: Пн дек 21, 2009 13:55:05
uldemir
Проблема не в этом. Это я не внимательно переписывал с другого монитора. Ну пусть там будет (1 downto 0). Сама суть заставить схему проходить состояния в заданной последовательности. Независимо вычислимые или невычислимые. Просто хочется задать таблицу. И не хочется писать длинный case.
Добавлено: Пн дек 21, 2009 14:48:43
nick17
попробуй так
architecture Behavioral of counter is
signal count_signal : std logic_vector (1 downto 0);
begin
process(clk)
begin
if clk'event and clk='1' then
count_signal <count_signal>"10") then
count_signal<="00";
end if;
with count_signal select
count <= "11" when "00",
"01" when "01",
"10" when "10",
"00" when others;
end process;
end Behavioral;
Добавлено: Пн дек 21, 2009 14:51:38
nick17
architecture Behavioral of counter is
signal count_signal : std logic_vector (1 downto 0);
begin
process(clk)
begin
if clk'event and clk='1' then
count_signal <count_signal>"10") then
count_signal<="00";
end if;
end if;
with count_signal select
count <= "11" when "00",
"01" when "01",
"10" when "10",
"00" when others;
end process;
end Behavioral;
Добавлено: Пн дек 21, 2009 15:34:59
nick17
Вот, синтезируется без ошибок -
Добавлено: Пн дек 21, 2009 19:32:05
uldemir
Да, спасибо, очевидно только так это можно организовать. Наверное применение перечислимого типа здесь неуместно. Хотелось написать список, чтобы бегать по нему в любом направлении, не создавая две таблицы переходов.
Добавлено: Пн дек 21, 2009 19:54:01
nick17
Что ваяешь? Я сам начинающий по ПЛИС

Добавлено: Пн дек 21, 2009 20:18:36
uldemir
Что ваяешь? Я сам начинающий по ПЛИС
Статью для Кота ;-). Я, наверное, перманентный начинающий. Надоело, что редактор схем грохается от каждого неосторожного шага и решил осваивать текстовые языки. Хотел начать с ABEL (на xilinx был сервис - заливаешь код, он в ответ .jed), но пока искал учебники убрали его поддержку за невостребованностью. Теперь вот пытаюсь VHDL освоить. Есть четыре учебника - да толку мало.
Добавлено: Пн дек 21, 2009 22:02:03
nick17
Я сначала в схематике пытался, но потом начал комбинировать, так показалось проще, например описываешь элемент, а затем создаешь его компонент. Мне тоже сложновато языки даются...Если будут вопросы пиши, попытаюсь помочь, вдвоем проще разобраться) Кстати вот хочу попробовать щас часики на CPLD сделать, так от делать нечего) как раз и в языке продвинусь

(надеюсь)
Добавлено: Пн дек 21, 2009 22:48:20
uldemir
nick17 писал(а):Кстати вот хочу попробовать щас часики на CPLD сделать, так от делать нечего) как раз и в языке продвинусь :) (надеюсь)
Вот их я и сделал ;-). В двух вариантах на ЖКИ и ИН-14. Правда для ЖКИ на xc9572 - т.е. не для батарейного питания. Сейчас пытаюсь забороть CoolrunnerII. но он не для наколенного монтажа. Нашел самую "растопыристую" микросхему из coolrunner-ов xc2c64a - в VQFP корпусе шаг 0.8 мм - все остальные 0.5. И пытался упхнуть часики. Вроде всего на 8 макроячеек меньше, но даже выбросив 10-разрядный делитель частоты всё-равно нехватает. Как-то он по другому организован, надо по-внимательнее даташит поизучать. Сейчас уговорил её на тактовую 8Гц с использованием фичи DualEdge. Потому что тактировать решил от cd4060, а у нее в делителе как раз дырка - на 16Гц нету вывода. 32Гц делить - ячеек нехватает, а 8Гц - вроде уже дискретизация будет нервировать. Теперь нужно будет подумать плату и на живом уже проверять. Посмотрим, действительно ли там будут микроамперы потребляемого тока...
Добавлено: Вт дек 22, 2009 05:59:46
nick17
Дааа, я вчера уже понял, после того как зашел на твой сайт, что часики уже одно из пройденных у тебя)) FPGA планируешь?))
Добавлено: Вт дек 22, 2009 20:26:49
uldemir
Когда-то наш руководитель кружка рассказывал об одном человеке, который публиковал конструкции в журнале Радио. И всегда это была одна и та же конструкция - "Красный или зелёный". Вроде на тот момент последняя была на микросхемах 155-й серии. А первая, говорят, была на лампах.
nick17 писал(а):Дааа, я вчера уже понял, после того как зашел на твой сайт, что часики уже одно из пройденных у тебя)) FPGA планируешь?))
Просто, когда осваиваешь что-то новое, пробуешь применить в уже известном. Вот у меня это часы и таймеры. А для FPGA не могу придумать пока достойной задачи. Потому как туда надо софт заливать. Значит нужен микроконтроллер. И микроконтроллер с памятью. Есть у меня пара платок-доноров с каким-то малым Spartan-ом. Но он тоже 0.5 мм TQFP.
Добавлено: Ср дек 23, 2009 19:25:35
nick17
0.5 это разве много?)
Добавлено: Пт дек 25, 2009 00:28:35
Spartan3E
-- А проще так
entity counter is
Port( clk in: std_logic;
count out : std_logic_vector (1 downto 0));
end counter;
architecture Behavioral of counter is
signal count_signal : std logic_vector (1 downto 0):= "00";
begin
process(clk)
begin
if clk'event and clk='1' then
count_signal <= count_signal+1;
end if;
end process;
with count_signal select
count <= "11" when "00",
"01" when "01",
"10" when "10",
"00" when others;
end Behavioral;
Добавлено: Вс дек 27, 2009 18:01:53
uldemir
Заборол. Вот что я хотел получить:
Код: Выделить всё
entity test is
Port ( clk : in STD_LOGIC;
count : out STD_LOGIC_VECTOR (1 downto 0));
end test;
architecture Behavioral of test is
type thd_table is array(integer range <>) of std_logic_vector(1 downto 0);
constant thd : thd_table:= (0 => "11",
1 => "01",
2 => "10");
signal thd_ptr : integer range 0 to thd'HIGH:= 0;
signal data_out : std_logic_vector(1 downto 0);
begin
process(clk)
begin
if clk'event and clk='1' then
if thd_ptr = thd'HIGH then
thd_ptr <= 0;
else
thd_ptr <= thd_ptr + 1;
End if;
data_out <= thd(thd_ptr);
end if;
end process;
count <= data_out;
end Behavioral;
Разумеется, суть не в двух разрядах, а в использовании типов и построении последовательностей.
Добавлено: Вс дек 27, 2009 22:10:30
Spartan3E
лучше так
entity test is
Port ( clk : in STD_LOGIC;
count : out STD_LOGIC_VECTOR (1 downto 0));
end test;
architecture Behavioral of test is
type thd_table is array(integer range <>) of
std_logic_vector(1 downto 0);
constant thd : thd_table:= (0 => "11",
1 => "01",
2 => "10");
signal thd_ptr : integer range 0 to thd'HIGH:= 0;
--signal data_out : std_logic_vector(1 downto 0);
begin
process(clk)
begin
if clk'event and clk='1' then
if thd_ptr = thd'HIGH then
thd_ptr <= 0;
else
thd_ptr <= thd_ptr + 1;
End if;
--data_out <= thd(thd_ptr);
end if;
end process;
count <= thd(thd_ptr);
end Behavioral;
Добавлено: Вс дек 27, 2009 23:32:29
uldemir
А можно задать вопрос? Чем лучше?
Добавлено: Пн дек 28, 2009 10:29:56
Spartan3E
uldemir писал(а):А можно задать вопрос? Чем лучше?
data_out не нужен и присвоение
count <= thd(thd_ptr) лучше вынести из синхронной обработки.
Re: Не могу выразить словами на VHDL
Добавлено: Вт авг 21, 2012 19:21:59
uldemir
У меня есть еще вопрос. Сделал пол-года назад проект - всё работает. Одно но - исходник содержит полторы тысячи строк. Нельзя ли как "уплотнить"? Дело в том, что куски однообразные. Здесь написана работа с устройством 1-wire. Модулю посылаются сигналы что передавать сброс, "1" или "0", а затем ожидается пока слот отработает, потом следующий бит. Беда в том, что сигнал state проходит почти все 256 состояний и в этом case каждое состояние расписать муторно. А еще муторнее это читать. Можно ли как-то объединить их циклом, что-ли?
Спойлер
Код: Выделить всё
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity thermo is
Port ( clk1mhz : in STD_LOGIC;
owin1 : in STD_LOGIC;
owin2 : in STD_LOGIC;
owout : out STD_LOGIC;
spullup: out STD_LOGIC;
crcerr1: out STD_LOGIC;
crcerr2: out STD_LOGIC;
cathodes : out STD_LOGIC_VECTOR (3 downto 0);
anodes : out STD_LOGIC_VECTOR (1 downto 0));
end thermo;
architecture Behavioral of thermo is
signal clk : std_logic := '0';
signal datain1 : std_logic := '0';
signal datain2 : std_logic := '0';
signal dataout : std_logic := '0';
signal wr_res : std_logic :='0';
signal ow_run : std_logic := '0';
signal crc_upd : std_logic :='0';
signal tsh_upd : std_logic_vector (1 downto 0) :="00";
signal state : std_logic_vector (7 downto 0) := (others => '0');
-- ds18s20 command codes
constant skip_ROM : std_logic_vector (7 downto 0) := X"CC";
constant Convert_T: std_logic_vector (7 downto 0) := X"44";
constant Read_Scrp: std_logic_vector (7 downto 0) := X"BE";
constant Read_ROM : std_logic_vector (7 downto 0) := X"33";
begin
process(clk)
begin
if clk'event and clk='1' then
-- Make reset
case state is
when X"00" =>
spullup <= '1';
wr_res <= '0';
ow_run <= '1';
state <= state+1;
when X"01" =>
if ow_run = '0' then
state <= state+1;
end if;
-- Send 0x33 - Read ROM
when X"02" =>
dataout <= Read_ROM(0);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"03" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"04" =>
dataout <= Read_ROM(1);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"05" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"06" =>
dataout <= Read_ROM(2);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"07" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"08" =>
dataout <= Read_ROM(3);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"09" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"0A" =>
dataout <= Read_ROM(4);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"0B" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"0C" =>
dataout <= Read_ROM(5);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"0D" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"0E" =>
dataout <= Read_ROM(6);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"0F" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"10" =>
dataout <= Read_ROM(7);
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"11" =>
if ow_run = '0' then
state <= state+1;
end if;
-- Read 4 bit of family code:
-- ds18b20 0x28 0001...,
-- ds18s20 0x10 0000...
when X"12" =>
dataout <= '1';
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"13" =>
if ow_run = '0' then
state <= state+1;
end if;
when X"14" =>
dataout <= '1';
wr_res <= '1';
ow_run <= '1';
state <= state+1;
when X"15" =>
if ow_run = '0' then
state <= state+1;
end if;
и так далее...