agathodaimon 0 22 ноября, 2020 Опубликовано 22 ноября, 2020 · Жалоба Добрый день, форумчане. Есть такая странная ситуация. Написал код для динамической индикации 7-сегментного индикатора. Все работает, однако наблюдаю странное поеведение. Разряд, который выступает следующим, светится тускло знаком предыдущего. Может кто увидит сразу и дкнет в проблему? пытался гуглить примеры, но они вроде от моего кода не слишком отличаются. Плис Altera Cyclone 4, EDI Quartus. module helloworlds ( input [3:0]btn, output [3:0]led , output reg [3:0] digits, output reg [7:0] dots, output speaker, input clk); assign led[0] = btn[0]; reg [23:0]CTCQ; reg [16:0]CTFQ; reg [16:0]freq; reg [1:0]dig = 2'd0; reg [3:0]curr_digit; reg [15:0]CNT; reg strobe = 1; reg [7:0]strobe_ct = 0; always @(posedge clk) begin CTCQ <= CTCQ + 1'd1; if (curr_digit == 4'd0 || curr_digit == 4'd8) CTFQ <= CTFQ + 1'd1; else CTFQ <= 14'd0; strobe_ct <= strobe_ct + 1'd1; if(strobe_ct == 8'hff) begin dig <= dig + 1'd1; end if(strobe_ct > 8'hf0) begin strobe = 0; end else begin strobe = 1; end curr_digit <= CNT >> (dig * 4); case(dig) 2'd0: digits = ~4'd1; 2'd1: digits = ~4'd2; 2'd2: digits = ~4'd4; 2'd3: digits = ~4'd8; endcase // // ___ // b | g | f // |___| // | a | // c |___| e // d if (strobe) begin case(curr_digit)// ABCDEFG 4'h0: dots = ~7'b0111111; 4'h1: dots = ~7'b0000110; 4'h2: dots = ~7'b1011011; 4'h3: dots = ~7'b1001111; 4'h4: dots = ~7'b1100110; 4'h5: dots = ~7'b1101101; 4'h6: dots = ~7'b1111101; 4'h7: dots = ~7'b0000111; 4'h8: dots = ~7'b1111111; 4'h9: dots = ~7'b1101111; 4'ha: dots = ~7'b1110111; 4'hb: dots = ~7'b1111100; 4'hc: dots = ~7'b0111001; 4'hd: dots = ~7'b1011110; 4'he: dots = ~7'b1111001; 4'hf: dots = ~7'b1110001; endcase end else begin dots = ~7'b0000000; end end // Speaker wire //assign speaker = CTFQ[16]; //always @(posedge CTCQ[23]) CTQ <= CTQ + 1'd1; always @(posedge CTCQ[23]) CNT <= CNT + 1'd1; //always digits = 4'd0; endmodule Моделирование пока не освоил... пока что не разобрался как это сделать. Выглядит это примерно как на фото, правда плохо видно. Четверка самого верхнего сегмента отдает восьмеркой, которая является предыдущем. Буду признателен любой наводке) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
agathodaimon 0 22 ноября, 2020 Опубликовано 22 ноября, 2020 · Жалоба Правда, симуляция говорит ровно то, что я вижу своими глазами. Переключение digits происходит до смены значения на dots. осталось теперь понять, почему это происходит) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 168 22 ноября, 2020 Опубликовано 22 ноября, 2020 · Жалоба На какой частоте это работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 22 ноября, 2020 Опубликовано 22 ноября, 2020 · Жалоба 44 минуты назад, agathodaimon сказал: Правда, симуляция говорит ровно то, что я вижу своими глазами. Переключение digits происходит до смены значения на dots. осталось теперь понять, почему это происходит) Разбивайте код на логические модули. Есть декодер семисегментного индикатора - значит оформляйте это в отдельный модуль. Чем легче читается код - тем проще найти в нем ошибки. Динамическая индикация для семисегментного индикатора - это по сути кольцевой сдвиговый регистр, где единичка бегает по кругу. В вашем коде это сделано неочевидно. через присвоение значений 1, 2, 4, 8 . А вообще такие штуки лучше делать цифровыми автоматами. И читаются легко, и поддерживаются легко. И при должном навыке занимают минимум ресурсов. Но при этом легко масштабируются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vasily_ 45 22 ноября, 2020 Опубликовано 22 ноября, 2020 · Жалоба 3 часа назад, agathodaimon сказал: Все работает, однако наблюдаю странное поведение. Разряд, который выступает следующим, светится тускло знаком предыдущего. Ничего странного. Сегмент сначала нужно выключить, и только потом включить следующий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
agathodaimon 0 23 ноября, 2020 Опубликовано 23 ноября, 2020 · Жалоба 14 hours ago, Plain said: На какой частоте это работает? На железке clk напрямую от кварца - 50МГц 13 hours ago, Flip-fl0p said: Разбивайте код на логические модули. Есть декодер семисегментного индикатора - значит оформляйте это в отдельный модуль. Чем легче читается код - тем проще найти в нем ошибки. Динамическая индикация для семисегментного индикатора - это по сути кольцевой сдвиговый регистр, где единичка бегает по кругу. В вашем коде это сделано неочевидно. через присвоение значений 1, 2, 4, 8 . А вообще такие штуки лучше делать цифровыми автоматами. И читаются легко, и поддерживаются легко. И при должном навыке занимают минимум ресурсов. Но при этом легко масштабируются. Да, спасибо! я и сам планировал разбить, только хотел вначале привести к рабочему варианту) По поводу сдвигового регистра, там получается выбор, либо сдвигать, и делать case на вот эту строчку curr_digit <= CNT >> (dig * 4); либо оставлять как было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 168 23 ноября, 2020 Опубликовано 23 ноября, 2020 · Жалоба 3 минуты назад, agathodaimon сказал: curr_digit <= CNT >> (dig * 4); Ну так этот генератор случайных чисел у Вас на системной частоте молотит — другого предназначения этой загогулины не видно, никаких данных для вывода на этот дисплей на входе модуля не указано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 23 ноября, 2020 Опубликовано 23 ноября, 2020 · Жалоба Поскольку я пишу на VHDL - то думаю могу приложить пример как бы я написал вывод на семисегментный индикатор. В моем примере перевод из двоичного кода осуществляется при помощи функции. Можно в виде отдельного модуля. Я тут показываю суть: есть 4 знака семисегментного индикатора. Для каждого знака индикатора описано свое состояние автомата, в котором этот знак включается. В этом же состоянии описано что за значение выводить на сегмент индикатора. Потом автомат переходит в следующее состояние, в котором зажигается новый знак. И так циклически автомат переключается по всем знакам. library IEEE; use IEEE.std_logic_1164.all; entity sign is port ( clk : in std_logic; in_sign0_tdata : in std_logic_vector(3 downto 0); -- Значение, которое нужно вывести на нулевом разряде индикатора in_sign1_tdata : in std_logic_vector(3 downto 0); in_sign2_tdata : in std_logic_vector(3 downto 0); in_sign3_tdata : in std_logic_vector(3 downto 0); sign_enable : out std_logic_vector(3 downto 0); -- Включение сегмента out_7SEGMENT_TDATA : out std_logic_vector(6 downto 0) -- Значение, выдаваемое на сегмент ); end entity; architecture RTL of sign is -- =========================================================== -- Функция возвращающая код семисегментного индикатора -- =========================================================== function GET_7SEGMENT_CODE ( binary_code : std_logic_vector ) return std_logic_vector is begin case binary_code is when x"0" => return "0111111"; when x"1" => return "0000110"; when x"2" => return "1011011"; when x"3" => return "1001111"; when x"4" => return "1100110"; when x"5" => return "1101101"; when x"6" => return "1111101"; when x"7" => return "0000111"; when x"8" => return "1111111"; when x"9" => return "1101111"; when x"A" => return "1110111"; when x"B" => return "1111100"; when x"C" => return "0111001"; when x"D" => return "1011110"; when x"E" => return "1111001"; when x"F" => return "1110001"; when others => return (others => '-'); end case; end function; type FSM_state is ( SIGN0 , SIGN1 , SIGN2 , SIGN3 ); signal press_state, next_state : FSM_state := SIGN0; signal sign_TDATA : std_logic_vector(3 downto 0); begin --======================================================== -- Процесс переключения состояний автомата --======================================================== press_state_to_next_state : process(clk) begin if (rising_edge(clk)) then press_state <= next_state; end if; end process; --======================================================== -- Процесс вычисления следующего состояния автомата --======================================================== next_state_calk : process(all) begin case press_state is when SIGN0 => next_state <= SIGN1; when SIGN1 => next_state <= SIGN2; when SIGN2 => next_state <= SIGN3; when SIGN3 => next_state <= SIGN0; when others => next_state <= SIGN0; end case; end process; --======================================================== -- Выходная логика работы автомата --======================================================== FSM_output_logic : process(all) begin sign_enable <= (others => '-'); sign_TDATA <= (others => '-'); case press_state is when SIGN0 => sign_enable <= "0001"; -- Зажигаем нужный разряд sign_TDATA <= in_sign0_tdata; -- На этот разряд выводим нужную нам цифру --====================================================================== when SIGN1 => sign_enable <= "0010"; sign_TDATA <= in_sign1_tdata; --====================================================================== when SIGN2 => sign_enable <= "0100"; sign_TDATA <= in_sign2_tdata; --====================================================================== when SIGN3 => sign_enable <= "1000"; sign_TDATA <= in_sign3_tdata; --====================================================================== when others => null; end case; end process; out_7SEGMENT_TDATA <= GET_7SEGMENT_CODE(sign_TDATA); end architecture; P.S. Интересно почему студентов не учат именно автоматному проектированию, как самому быстрому, простому и надежному способу описывать свои схемы ? 20 часов назад, Vasily_ сказал: Ничего странного. Сегмент сначала нужно выключить, и только потом включить следующий. Зачем ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vasily_ 45 23 ноября, 2020 Опубликовано 23 ноября, 2020 · Жалоба 27 минут назад, Flip-fl0p сказал: Зачем ? Что-бы не было подсветки соседнего сегмента, или вы считаете что светодиоды не имеют инерции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 23 ноября, 2020 Опубликовано 23 ноября, 2020 · Жалоба 19 минут назад, Vasily_ сказал: Что-бы не было подсветки соседнего сегмента, или вы считаете что светодиоды не имеют инерции? При правильно подобранной частоте тактирования инерцией светодиода можно смело пренебречь. Конечно если каждые 5..10 нс. переключать сегменты нужно будет учитывать это. А если переключать раз в миллисекунду, то на инерцию пофиг, если у нас тас не весит конденсатор)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Strob 0 24 ноября, 2020 Опубликовано 24 ноября, 2020 · Жалоба 11 hours ago, Vasily_ said: Что-бы не было подсветки соседнего сегмента, или вы считаете что светодиоды не имеют инерции? Не очень понятно, как связана инерция диода и подсветка соседнего сегмента. Соседний сегмент - это другой диод. Чтобы не было засветки надо обеспечить одновременное переключение сигналов. Или дэдтаймы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
agathodaimon 0 24 ноября, 2020 Опубликовано 24 ноября, 2020 · Жалоба Кажется, я понял в чем у меня проблема. На симуляторе сейчас все красиво, приду домой - проверю, если все ок, выложу свой код :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 24 ноября, 2020 Опубликовано 24 ноября, 2020 (изменено) · Жалоба Если что, у альтеры в cookbook есть пример семисегментного дисплея + последние квартусы могут генерить уже готовые шаблоны модули этого дела. Но там как то все просто до безобразия Изменено 24 ноября, 2020 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nemos760 0 25 ноября, 2020 Опубликовано 25 ноября, 2020 · Жалоба По сути тоже самое, что функция у Flip-Flop, только в виде модуля и выводит в 16-коде. На вход подаются уже готовые данные из другого модуля (выход мультиплексора, управляемого машиной состояний). Никакой проблемы с засветкой никогда не наблюдал. И да, с функцией было бы удобнее. Quote library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity HEX_encoder is port( DATA: in unsigned(3 downto 0); HEX: out std_logic_vector(6 downto 0) ); end entity HEX_encoder; architecture rtl of HEX_encoder is begin with to_integer(DATA) select HEX<= "1000000" when 16#0#, "1111001" when 16#1#, "0100100" when 16#2#, "0110000" when 16#3#, "0011001" when 16#4#, "0010010" when 16#5#, "0000010" when 16#6#, "1111000" when 16#7#, "0000000" when 16#8#, "0010000" when 16#9#, "0001000" when 16#A#, "0000011" when 16#B#, "1000110" when 16#C#, "0100001" when 16#D#, "0000110" when 16#E#, "0001110" when 16#F#, "1111111" when others; end rtl; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 ноября, 2020 Опубликовано 25 ноября, 2020 · Жалоба 38 минут назад, Nemos760 сказал: По сути тоже самое, что функция у Flip-Flop, только в виде модуля и выводит в 16-коде. На вход подаются уже готовые данные из другого модуля (выход мультиплексора, управляемого машиной состояний). Никакой проблемы с засветкой никогда не наблюдал. И да, с функцией было бы удобнее. Я предпочитаю преобразователь из двоичного в семи сегментный держать в виде отдельного модуля с параметром каким логичесим уровнем зажигать сегмент. Хотя все чаще и чаще я стал в своём коде применять различного рода функции, хоть раньше этого и не любил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться