whiteTigr 0 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба Может кто-нибудь подкинуть интересных задачек на VHDL для развития мозгов? Возможно, с различными условиями типа "занять не больше ячеек X", "сделать без умножалок", "посчитать не более, чем за X тактов" и т.п. Или просто интересные задачи без каких либо условий. Поиск в гугле практически ничего не дает. Попадаются ссылки на форумы, "задачи" студентов уровня "как сделать c = a + b". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба Может кто-нибудь подкинуть интересных задачек на VHDL для развития мозгов? по форуму куча подобного с примерами раскидана, bin2bcd, count_ones, divider, FWPT FIFO, ff_ram_buffer и т.д. и т.п. %) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whiteTigr 0 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба по форуму куча подобного с примерами раскидана, bin2bcd, count_ones, divider, FWPT FIFO, ff_ram_buffer и т.д. и т.п. %) Начнемс с начала. Bin2Bcd. :) Попробую сделать его параметризованым с InputWidth (максимум 32 бита) в generic. Считать буду за несколько тактов простым вычитанием (худший случай 1_999_999_999, должно быть ~90 тактов на вычисление). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба Считать буду за несколько тактов простым вычитанием (худший случай 1_999_999_999, должно быть ~90 тактов на вычисление). в соседних темах делают намного быстрее ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whiteTigr 0 2 ноября, 2011 Опубликовано 2 ноября, 2011 (изменено) · Жалоба в соседних темах делают намного быстрее ;) Хм, реализовал решение "в лоб", в ISIM работает примерно также, как и ожидалось (83 такта получилось). Сейчас поищу, как быстрее все это считают. :) Изменено 2 ноября, 2011 пользователем whiteTigr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба Хм, реализовал решение "в лоб", в ISIM работает примерно также, как и ожилась (83 такта получилось). Сейчас поищу, как быстрее все это считают. :) а поделиться ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whiteTigr 0 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба а поделиться ;) Вот так получилось. Теперь можно меня громко обругать за корявость кода. :) П.С.: к сожалению, не помню тега, чтобы блок кода был со скроллером. 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; use IEEE.Math_real.ALL; entity bin2bcd is Generic( InputWidth: integer := 8; OutputWidth: integer := 12 ); Port ( clk : in STD_LOGIC; d : in STD_LOGIC_VECTOR (InputWidth-1 downto 0); q : out STD_LOGIC_VECTOR (OutputWidth-1 downto 0); nd: out std_logic); end bin2bcd; architecture Behavioral of bin2bcd is constant NumberOfDigits: integer := integer(Ceil(Log10(real(2**InputWidth)))); constant NeededOutputWidth: integer := NumberOfDigits * 4; type TCmpTable is array(0 to 8) of std_logic_vector(31 downto 0); constant CmpTable: TCmpTable := (x"0000_000A", x"0000_0064", x"0000_03E8", x"0000_2710", x"0001_86A0", x"000F_4240", x"0098_9680", x"05F5_E100", x"3B9A_CA00"); type TAddTable is array(0 to 8) of std_logic_vector(39 downto 0); constant AddTable: TAddTable := (x"00_0000_0006", x"00_0000_009C", x"00_0000_0C18", x"00_0000_D8F0", x"00_000E_7960", x"00_00F0_BDC0", x"00_0F67_6980", x"00_FA0A_1F00", x"0F_C465_3600"); signal dBuf: std_logic_vector(InputWidth-1 downto 0); signal qBuf: std_logic_vector(NeededOutputWidth-1 downto 0); signal CurDigit: integer range 0 to 8; signal CmpValue: std_logic_vector(InputWidth-1 downto 0); signal AddValue: std_logic_vector(NeededOutputWidth-1 downto 0); signal State: integer range 0 to 2 := 0; begin --не знаю как преобразовать Integer в строку, чтобы вывести предупредение --PROCESS BEGIN --ASSERT (OutputWidth = NeededOutputWidth);-- REPORT "Needed OutputWidth = " & string(NeededOutputWidth) SEVERITY WARNING; --END PROCESS; process(clk) begin if rising_edge(clk) then CmpValue <= CmpTable(CurDigit)(InputWidth-1 downto 0); AddValue <= AddTable(CurDigit)(NeededOutputWidth-1 downto 0); end if; end process; process(clk) begin if rising_edge(clk) then case State is when 0 => q <= qBuf(OutputWidth-1 downto 0); qBuf <= conv_std_logic_vector(0, NeededOutputWidth - InputWidth) & d; dBuf <= d; nd <= '1'; CurDigit <= NumberOfDigits - 2; State <= 1; when 1 => nd <= '0'; -- такт на чтение данных из памяти State <= 2; when 2 => if dBuf >= CmpValue then dBuf <= dBuf - CmpValue; qBuf <= qBuf + AddValue; elsif CurDigit = 0 then State <= 0; else CurDigit <= CurDigit - 1; State <= 1; end if; when others => State <= 0; end case; end if; end process; end Behavioral; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whiteTigr 0 2 ноября, 2011 Опубликовано 2 ноября, 2011 · Жалоба Вариант номер 2. За основу взята pdf'ка http://people.ee.duke.edu/~dwyer/courses/e...D_Converter.pdf Это уже больше похоже на нормальное преобразование. Худших случаев нет, преобразование длится (InputWidth*2 + 1) тактов. Теперь модуль дополнительно ждет изменения сигнала на входе, перед началом преобразования. Завтра проверю занимаемые ресурсы в этих двух вариантах, сейчас уже точно не помню сколько получалось в первом, вроде бы примерно столько же. Возможно на форуме уже что-то подобное было, но свою главную задачу я выполнил - не умер от скуки. :) 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; use IEEE.Math_real.ALL; entity bin2bcd_ver2 is Generic( InputWidth: integer := 32; OutputWidth: integer := 40 ); Port ( clk : in STD_LOGIC; d : in STD_LOGIC_VECTOR (InputWidth-1 downto 0); q : out STD_LOGIC_VECTOR (OutputWidth-1 downto 0); nd : out STD_LOGIC); end bin2bcd_ver2; architecture Behavioral of bin2bcd_ver2 is constant NumberOfDigits: integer := integer(Ceil(real(InputWidth) * 3.012)); constant NeededOutputWidth: integer := NumberOfDigits * 4; signal LastD: std_logic_vector(InputWidth-1 downto 0); signal dBuf: std_logic_vector(InputWidth-1 downto 0); signal qBuf: std_logic_vector(NeededOutputWidth-1 downto 0); type TState is (Buffering, Shifting, Correcting); signal State, LastState: TState; signal ShiftCounter: integer range 0 to InputWidth; begin process(clk) begin if rising_edge(clk) then case State is when Buffering => dBuf <= d; qBuf <= (others => '0'); ShiftCounter <= InputWidth; LastD <= d; if LastD /= d then State <= Shifting; end if; when Shifting => qBuf(NeededOutputWidth-1 downto 1) <= qBuf(NeededOutputWidth-2 downto 0); qBuf(0) <= dBuf(InputWidth-1); dBuf(InputWidth-1 downto 1) <= dBuf(InputWidth-2 downto 0); dBuf(0) <= '0'; ShiftCounter <= ShiftCounter - 1; State <= Correcting; when Correcting => if ShiftCounter > 0 then State <= Shifting; for i in 0 to NumberOfDigits-1 loop if qBuf((i * 4) + 3 downto i * 4) > x"4" then qBuf((i * 4) + 3 downto i * 4) <= qBuf((i * 4) + 3 downto i * 4) + x"3"; end if; end loop; else State <= Buffering; end if; when others => State <= Buffering; end case; LastState <= State; if (LastState /= Buffering) and (State = Buffering) then q <= qBuf(OutputWidth-1 downto 0); nd <= '1'; else nd <= '0'; end if; end if; end process; end Behavioral; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whiteTigr 0 3 ноября, 2011 Опубликовано 3 ноября, 2011 (изменено) · Жалоба Вариант 2.1. Совмещены состояния Shifting и Correcting, теперь преобразование длится в 2 раза меньше времени "InputWidth + 1" такт (по результатам синтеза на Spartan3S400 выдает максимальную частоту 130Мгц). Добавлена таблица Correct, вместо условия "if (a > 4) then a += 3;", это немного уменьшило занимаемые ресурсы. Исправлена досадная опечатка в вычислении NumberOfDigits. Границы применимости: минимальное число десятичных разрядов = 2 (InputWidth >= 7). максимальное, должно быть, не ограничено. Тестировал на 64 бита входного сигнала и 80 бит выходного. Занимаемые ресурсы (InputWidth = 32, OutputWidth = 40): 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; use IEEE.Math_real.ALL; entity bin2bcd_ver2 is Generic( InputWidth: integer := 32; OutputWidth: integer := 40 ); Port ( clk : in STD_LOGIC; d : in STD_LOGIC_VECTOR (InputWidth-1 downto 0); q : out STD_LOGIC_VECTOR (OutputWidth-1 downto 0); nd : out STD_LOGIC); end bin2bcd_ver2; architecture Behavioral of bin2bcd_ver2 is constant NumberOfDigits: integer := integer(Ceil(real(InputWidth) * 0.30103)); constant NeededOutputWidth: integer := NumberOfDigits * 4; type TCorrectTable is array(0 to 15) of std_logic_vector(3 downto 0); signal Correct: TCorrectTable := (x"0", x"1", x"2", x"3", x"4", x"8", x"9", x"A", x"B", x"C", x"F", x"F", x"F", x"F", x"F", x"F" ); signal LastD: std_logic_vector(InputWidth-1 downto 0); signal dBuf: std_logic_vector(InputWidth-1 downto 0); signal qBuf: std_logic_vector(NeededOutputWidth-1 downto 0); type TState is (Buffering, Shifting); signal State, LastState: TState; signal ShiftCounter: integer range 0 to InputWidth-1; begin process(clk) begin if rising_edge(clk) then case State is when Buffering => dBuf <= d; qBuf <= (others => '0'); ShiftCounter <= InputWidth-1; LastD <= d; if LastD /= d then State <= Shifting; end if; when Shifting => for i in 1 to NumberOfDigits-1 loop if ShiftCounter > 0 then qBuf((i * 4) + 3 downto i * 4) <= Correct(conv_integer(qBuf((i * 4) + 2 downto i * 4 - 1))); else qBuf((i * 4) + 3 downto i * 4) <= qBuf((i * 4) + 2 downto i * 4 - 1); end if; end loop; if ShiftCounter > 0 then qBuf(3 downto 0) <= Correct(conv_integer(qBuf(2 downto 0) & dBuf(InputWidth-1))); else qBuf(3 downto 0) <= qBuf(2 downto 0) & dBuf(InputWidth-1); end if; dBuf(InputWidth-1 downto 1) <= dBuf(InputWidth-2 downto 0); dBuf(0) <= '0'; if ShiftCounter > 0 then ShiftCounter <= ShiftCounter - 1; else State <= Buffering; end if; when others => State <= Buffering; end case; LastState <= State; if (LastState /= Buffering) and (State = Buffering) then q <= qBuf(OutputWidth-1 downto 0); nd <= '1'; else nd <= '0'; end if; end if; end process; end Behavioral; Изменено 3 ноября, 2011 пользователем whiteTigr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться