Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Cyclone iii глючит
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
shide_3
Ребят, нужна помощь, или подсказка. опыт работы с плисаками уже 5 лет. но вот затычка, алгоритм вроде простой, по сравнению с тем что приходилось раньше писать. (могу выложить код). но пока вопрос: алгоритм работает неустойчиво, на симуляторе все Ок, но в железе через некоторое время затыкается и все. может ли быть из за того что большая тактовая частота используется (из PLL) - 250 МГц?
wolfman
А чуть конкретнее?
TRILLER
"может ли быть из за того что большая тактовая частота используется (из PLL) - 250 МГц" - может) Скорее всего какой-то триггер в метостабильность входит.
shide_3
короче, попробовал с вдвое меньшей частотой- тоже самое ((. в общем, выкладываю код
CODE

entity proj is
Port (x : in std_logic_vector (5 downto 1);
y : in std_logic_vector (5 downto 1);
gate : out std_logic_vector (4 downto 1);
veto : in std_logic_vector (2 downto 1);
rst : in std_logic;


SA : in std_logic_vector (9 downto 0);
SD : inout std_logic_vector (7 downto 0);
AEN : in std_logic;
IOW : in std_logic;
IOR : in std_logic;

busy :out std_logic;
intr :out std_logic;
datastb :in std_logic;
addrstb :in std_logic;
writ: in std_logic;
data : out std_logic_vector (7 downto 0);
reset : in std_logic;

inclk : in std_logic;

D_p_ctrl :in std_logic_vector (3 downto 0);
D_s_ctrl :in std_logic_vector (3 downto 0);
G1_ctrl :in std_logic_vector (3 downto 0);
G2_ctrl :in std_logic_vector (3 downto 0);
Go_ctrl :in std_logic;

G1_QDCX:out std_logic;
G2_QDCX:out std_logic;
G1_QDCY:out std_logic;
G2_QDCY:out std_logic;
Go_out: out std_logic;
Tr1_out :out std_logic;
G1_out :out std_logic;
G2_out :out std_logic;
D_p_out :out std_logic;
D_s_out :out std_logic;
IRQ_out :out std_logic;
T_out :out std_logic;
RS_out :out std_logic;
TP1 :out std_logic;
TP2 :out std_logic


);
end proj;

architecture Behavioral of proj is

type statetype is (s0,s1,s2,s3,s4,s5,s6);

signal sm : statetype;


signal XX : std_logic;
signal YY : std_logic;
signal X_1 : std_logic;
signal Y_1 : std_logic;
signal Go : std_logic;
signal Tr1 : std_logic;
signal Go_reg : std_logic;
signal Go_reg1 : std_logic;
signal Go_reg2 : std_logic;
signal G1 : std_logic;
signal G2 : std_logic;
signal D_p : std_logic;
signal D_s : std_logic;
signal IRQ : std_logic;
signal T : std_logic;
signal RS : std_logic;
signal pc : std_logic_vector (3 downto 0);
signal SG1 : std_logic_vector (4 downto 0);
signal SG2 : std_logic_vector (6 downto 0);
signal pause1 : std_logic_vector (7 downto 0);
signal pause2 : std_logic_vector (14 downto 0);
signal xy : std_logic_vector (9 downto 0);
signal xy_reg : std_logic_vector (9 downto 0);
signal xy_reg1 : std_logic_vector (9 downto 0);
signal Rg1 : std_logic_vector (9 downto 0);
signal Rg2 : std_logic_vector (9 downto 0);
signal data_buf : std_logic_vector (7 downto 0);
signal SD_buf : std_logic_vector (7 downto 0);
signal cnt1 : std_logic_vector (15 downto 0);
signal cnt2 : std_logic_vector (15 downto 0);
signal cnt3 : std_logic_vector (15 downto 0);
signal cnt4 : std_logic_vector (15 downto 0);
signal cnt5 : std_logic_vector (15 downto 0);
signal cnt6 : std_logic_vector (15 downto 0);
signal cnt7 : std_logic_vector (15 downto 0);
signal cnt8 : std_logic_vector (15 downto 0);
signal cnt9 : std_logic_vector (15 downto 0);
signal cnt10 : std_logic_vector (15 downto 0);
signal cnt_wait : std_logic_vector (6 downto 0);

signal cnt_data : std_logic_vector (7 downto 0);

signal clk : std_logic;
signal clk1 : std_logic;
signal busyy : std_logic;
signal xxx : std_logic;
signal datastb1 : std_logic;
signal datastb2 : std_logic;
signal datastb3 : std_logic;
shared variable i : integer;
--signal clk1 : std_logic;
begin

pll : entity pll200
port map
(
inclk0 => inclk,
c0 => clk,
c1 => clk1
);




process (clk1, rst)
begin


end process;


process (x, y, XX, YY, sm)
begin
if (sm = s0 or sm = s1) then
--TP2 <= XX;
G1_QDCX <= XX;
G1_QDCY <= YY;
--gate(1) <= XX;
--gate(2) <= YY;
--gate(1) <= clk1;
--gate(2) <= clk1;
else G1_QDCX <= '0';G1_QDCY <= '0';
end if;
if (sm = s3 or sm = s4) then
G2_QDCX <= XX;
G2_QDCY <= YY;
--gate(3) <= XX;
--gate(4) <= YY;
--gate(3) <= clk1;
--gate(4) <= clk1;
else G2_QDCX <= '0';G2_QDCY <= '0';
end if;
--if (sm /= s2 ) then
--X_1_out <= XX;
--Y_1_out <= YY;
--else X_1_out <= '0';Y_1_out <= '0';
--end if;
XX <= x(1) or x(2) or x(3) or x(4) or x(5);
YY <= y(1) or y(2) or y(3) or y(4) or y(5);
Go <= XX or YY;
xy <= x&y;

end process;

process (x, clk)
begin
if rising_edge (clk) then
xy_reg <= xy;
xy_reg1 <= xy_reg;
Go_reg <= Go;
Go_reg1 <= Go_reg;
Tr1 <= Go_reg1 and (not Go_reg);
case sm is
when s0 =>
if Go_reg = '1' then
sm <= s1; G1 <= '1';
else sm <= s0;
end if;
when s1 =>
if (SG1 = "11001" and Tr1 = '0') then
G1 <= '0'; sm <= s1;
elsif (SG1 /= "11001" and Tr1 = '1') then sm <= s2; D_p <= '1';SG1 <= SG1 + '1';
elsif (SG1 /= "11001" and Tr1 = '0') then SG1 <= SG1 + '1'; sm <= s1;
elsif (SG1 = "11001" and Tr1 = '1') then G1 <= '0'; sm <= s2; D_p <= '1';
end if;
when s2 =>
if SG1 = "11001" then
G1 <= '0';
else SG1 <= SG1 + '1';
end if;
if pause1 = "11111010" then
pause1 <= (others => '0'); sm <= s3; D_p <= '0'; D_s <= '1';SG1 <= (others => '0');
else pause1 <= pause1 + '1'; sm <= s2;
end if;
when s3 =>
if (pause2 /= "10011100010000" and Go_reg = '0') then
pause2 <= pause2 + '1'; sm <= s3;
elsif (pause2 = "10011100010000" and Go_reg = '0') then
sm <= s6; pause2 <= (others => '0'); D_s <= '0';
intr <= '1';
elsif (pause2 /= "10011100010000" and Go_reg = '1') then
sm <= s4; D_s <= '0'; G2 <= '1';
elsif (pause2 = "10011100010000" and Go_reg = '1') then sm <= s4; D_s <= '0'; G2 <= '1';
end if;
when s4 =>
if (SG2 = "1100100" and Tr1 = '0') then
G2 <= '0'; sm <= s4;
elsif (SG2 /= "1100100" and Tr1 = '1') then sm <= s5; SG2 <= SG2 + '1';
elsif (SG2 /= "1100100" and Tr1 = '0') then SG2 <= SG2 + '1'; sm <= s4;
elsif (SG2 = "1100100" and Tr1 = '1') then G2 <= '0'; sm <= s5;
end if;
-- if SG2 = "0011" then
-- SG2 <= (others => '0'); G2 <= '0'; sm <= s0;
-- else SG2 <= SG2 + '1'; sm <= s4;
-- end if;
when s5 =>
if SG2 = "1100100" then
G2 <= '0';SG2 <= (others => '0');sm <= s6 ;
intr <= '1';
else SG2 <= SG2 + '1'; sm <= s5;
end if;
when s6 =>
if reset = '0' then
intr <= '0';
pause2 <= (others => '0');Rg1 <= (others => '0');Rg2 <= (others => '0'); sm <= s0;
else sm <= s6;
end if;

end case;


if G1 = '1' and xy_reg1(1) = '1' then Rg1(1) <= '1';end if;
if G1 = '1' and xy_reg1(2) = '1' then Rg1(2) <= '1';end if;
if G1 = '1' and xy_reg1(3) = '1' then Rg1(3) <= '1';end if;
if G1 = '1' and xy_reg1(4) = '1' then Rg1(4) <= '1';end if;
if G1 = '1' and xy_reg1(5) = '1' then Rg1(5) <= '1';end if;
if G1 = '1' and xy_reg1(6) = '1' then Rg1(6) <= '1';end if;
if G1 = '1' and xy_reg1(7) = '1' then Rg1(7) <= '1';end if;
if G1 = '1' and xy_reg1(8) = '1' then Rg1(8) <= '1';end if;
if G1 = '1' and xy_reg1(9) = '1' then Rg1(9) <= '1';end if;
if G1 = '1' and xy_reg1(0) = '1' then Rg1(0) <= '1';end if;

if G2 = '1' and xy_reg1(1) = '1' then Rg2(1) <= '1';end if;
if G2 = '1' and xy_reg1(2) = '1' then Rg2(2) <= '1';end if;
if G2 = '1' and xy_reg1(3) = '1' then Rg2(3) <= '1';end if;
if G2 = '1' and xy_reg1(4) = '1' then Rg2(4) <= '1';end if;
if G2 = '1' and xy_reg1(5) = '1' then Rg2(5) <= '1';end if;
if G2 = '1' and xy_reg1(6) = '1' then Rg2(6) <= '1';end if;
if G2 = '1' and xy_reg1(7) = '1' then Rg2(7) <= '1';end if;
if G2 = '1' and xy_reg1(8) = '1' then Rg2(8) <= '1';end if;
if G2 = '1' and xy_reg1(9) = '1' then Rg2(9) <= '1';end if;
if G2 = '1' and xy_reg1(0) = '1' then Rg2(0) <= '1';end if;

if datastb = '0' then cnt_wait <= cnt_wait + '1';
else cnt_wait <= (others => '0');
end if;

if cnt_wait = "1111101" then busyy <= '1';
elsif datastb = '1' then busyy <= '0';
end if;
datastb1 <= datastb;
datastb2 <= datastb1;
datastb3 <= datastb1 and (not datastb2);
if datastb3 = '1' then
pc <= pc + '1';
end if;
end if;
end process;

process (writ, datastb, pc, Rg1, Rg2, pause2)
begin


if datastb = '0' then
--data_buf <= "10101010";
--data_buf <= cnt_data;
--busy <= '1';
if pc = x"0" then data_buf <= '0'&'0'&'0'&Rg2 (9 downto 5);
elsif pc = x"1" then data_buf <= '0'&'0'&'0'&Rg2 (4 downto 0);
elsif pc = x"2" then data_buf <= '0'&'0'&'0'&Rg1 (9 downto 5);
elsif pc = x"3" then data_buf <= '0'&'0'&'0'&Rg1 (4 downto 0);
elsif pc = x"4" then data_buf <= pause2 (7 downto 0);
elsif pc = x"5" then data_buf <= '0'& pause2(14 downto 8);
-- if pc = x"0" then data_buf <= "00000101";
-- elsif pc = x"1" then data_buf <= "00001010";
-- elsif pc = x"2" then data_buf <= "00001111";
-- elsif pc = x"3" then data_buf <= "00010100";
-- elsif pc = x"4" then data_buf <= "00011001";
else data_buf <= (others => '0');
end if;
else data_buf <= (others => 'Z');
--busy <= '0';
end if;
end process;



Go_out <= Go;
Tr1_out <= Tr1;
G1_out <= G1;
G2_out <= G2;
D_p_out <= D_p;
D_s_out <= D_s;
IRQ_out <= IRQ;
T_out <= T;
RS_out <= RS;
data <= data_buf;
SD <= SD_buf;
--busy <= '0';
--intr <= '1';
--data <= "11111111";
TP1 <= reset;
TP2 <= YY;
busy <= busyy;

end behavioral;

в основном прошу обратить внимание на машину состояний, кажется в этом весь изюм


суть такова. есть сигналы (x (4:0) и y (4:0)). при поступлении любого из битов этих сигналов запускается машина, вырабатывается сигнал разрешения записи в регистр, затем после спада данного сигнала ждем 1 мкс, затем ждем следующего сигнала 40 мкс, если он пришел, то вырабатывается сигнал записи во второй регистр, и далее после спада вырабатывается intr (запрос на чтение). компьютер по LPT EPP считывает эти 2 регистра и посылает сброс. так вот, проблема в том что моя логика не ловит сброс и логика затыкается, и машина не переходит в исходное состояние...

может попробовать без машины состояний? с ними все время какие-то глюки происходят
Serhiy_UA
Условный переход в FSM корректен тогда, когда опрашиваемый сигнал буферирован той же частотой, какой синхронизируется FSM. Иногда его буферируют дважды.
Корректность синтеза FSM проверяется по условным переходам от входных сигналов, т.е. буферированы эти сигналы или нет...
Еще, поработайте с SignalTap II Logic Analyzer...
alexPec
Цитата(shide_3 @ Sep 5 2012, 11:07) *
Ребят, нужна помощь, или подсказка. опыт работы с плисаками уже 5 лет. но вот затычка, алгоритм вроде простой, по сравнению с тем что приходилось раньше писать. (могу выложить код). но пока вопрос: алгоритм работает неустойчиво, на симуляторе все Ок, но в железе через некоторое время затыкается и все. может ли быть из за того что большая тактовая частота используется (из PLL) - 250 МГц?


Выведите locked в сигнал-тап и посмотрите не слетает ли захват.
iosifk
Цитата(shide_3 @ Sep 5 2012, 12:46) *
суть такова. есть сигналы (x (4:0) и y (4:0)). при поступлении любого из битов этих сигналов запускается машина, вырабатывается сигнал разрешения записи в регистр, затем после спада данного сигнала ждем 1 мкс, затем ждем следующего сигнала 40 мкс, если он пришел, то вырабатывается сигнал записи во второй регистр, и далее после спада вырабатывается intr (запрос на чтение). компьютер по LPT EPP считывает эти 2 регистра и посылает сброс. так вот, проблема в том что моя логика не ловит сброс и логика затыкается, и машина не переходит в исходное состояние...

может попробовать без машины состояний? с ними все время какие-то глюки происходят


1. Почему Вы считаете, что изменения x и y соответствуют тактовой? Если это не так, то сделайте CDC...
2. Есть ли дребезг на этих сигналах? Если есть, то сделайте фильтр, 3-5 ступеней, чтобы убрать дребезг.
3. Если Вы умеете читать-писать из хоста, то самое простое - это прочесть состояние автомата. Если он находится в неправильном состоянии - сделайте состояние автомата по умолчанию, чтобы он из неправильных состояний выходил сам...
4. Код у Вас довольно занудный, в деталях я не смотрел... Пишите плохо! Я такие вещи делаю на программируемом таймере. Примеры у меня на сайте, в статьях - "Краткий Курс..."... При использовании таймера логика в автомате становится значительно проще и автомат бегает быстрее... Да и текст читать легче... Кстати, полное отсутствие комментариев - залог больших проблем. Читайте об этом там - же... Если уж просите помощи, так не ленитесь облегчить понимание Ваших кодов...
5. Если не лень, сделайте от хоста регистр, который позволял бы автомату делать только один шаг. И дальше, как в микроконтроллерах, "Точка останова" - исходное, и по шагам. Читаете состояние, разрешаете сделать шаг - снова читаете... Возможно и поможет... А возможно, что логики добавится и не поможет...
6. Сигнал-тап - про это уже сказали...
7. Все сигналы, которые идут от хоста должны быть обработаны как CDC. Скорее всего дело в Вашем "ресете", который попадает в метастабильность... Читать там-же!
TRILLER
Глянте сигнал "reset", может он всегда в единице висит?
shide_3
Цитата(TRILLER @ Sep 5 2012, 12:31) *
Глянте сигнал "reset", может он всегда в единице висит?

не, нормальный ресет-где-то около 100 нс

Цитата(iosifk @ Sep 5 2012, 12:29) *
2. Есть ли дребезг на этих сигналах? Если есть, то сделайте фильтр, 3-5 ступеней, чтобы убрать дребезг.

меня интересуют только биты этих сигналов по отдельности, а какой фильтр Вы имеете ввиду? усреднение-это когда оцифрованный сигнал, а у меня только логические сигналы - 10 бит.
а что такое CQC?

я наверное плохо изъясняюсь. не 2 пятибитных сигнала, а 10 однобитных

Цитата(iosifk @ Sep 5 2012, 12:29) *
4. Я такие вещи делаю на программируемом таймере.

а разве у FPGA есть программируемые таймеры?


не пойму, как использовать этот сигнал тап. он пишет - Device not detected и я не могу запустить анализатор
iosifk
Цитата(shide_3 @ Sep 5 2012, 15:12) *
не, нормальный ресет-где-то около 100 нс


меня интересуют только биты этих сигналов по отдельности, а какой фильтр Вы имеете ввиду? усреднение-это когда оцифрованный сигнал, а у меня только логические сигналы - 10 бит.
а что такое CQC?

я наверное плохо изъясняюсь. не 2 пятибитных сигнала, а 10 однобитных


а разве у FPGA есть программируемые таймеры?


не пойму, как использовать этот сигнал тап. он пишет - Device not detected и я не могу запустить анализатор

Объясняю еще раз. Сигнал "Сброс" из хоста приходит на автомат асинхронно. Читайте главу о Сбросе...
CDC - пересечение клоковых доменов.
Цифровой фильтр на сигналы делается "вручную"... Сдвиговый регистр на 3-5 разрядов. Если 3 разряда нули - значаит =0, если 1, значит дребезг кончился и стоит 1, как минимум 3 такта фильтрации. Выбираете сигнал разрешения на регистр так, чтобы переходный процесс закончился...
Таймер делается "вручную"...
Примеры того и другого я еще раз приводить не хочу! И так достаточно я все разжевал на примерно 200 страницах....
shide_3
Цитата(iosifk @ Sep 5 2012, 14:26) *
Объясняю еще раз. Сигнал "Сброс" из хоста приходит на автомат асинхронно. Читайте главу о Сбросе...

вроде бы, длительности сброса 100 нс должно быть предостаточно при частоте 250 Мгц
Alex11
Проблема не с длительностью сброса (так же, как и с остальными входными сигналами), а с тем, когда он заканчивается относительно клока. Он же приходит асинхронно, а дальше как повезет. Если сигнал пришел за 4 нс до клока, то все успеет переключиться, а если за 1 - то может быть, что из, скажем, двух триггеров, которые по логике должны переключиться в этот момент один успел, а задержка до второго 1.5 нс - он не успел. В итоге Вы получаете совсем не то состояние автомата, которое нужно. При этом, заметьте, от частоты клока это не зависит. Плюс к этому могут быть еще проблемы с метастабильностью, как отмечалось выше.
Sergey_Bekrenyov
пост-рут или пост-фит симуляцию попробуйте первым делом
Sergey_Bekrenyov
пост-рут или пост-фит симуляцию попробуйте первым делом
shide_3
спасибо всем кто дал совет и г-ну Каршенбойму за ссылку на его полезный ресурс.
проблема была в коде и немножко в схеме
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.