CaPpuCcino 0 16 апреля, 2011 Опубликовано 16 апреля, 2011 · Жалоба да я тоже пользуюсь 2-пробельной табуляцией. именно поэтому так широко размазано и получилось. но думаю это переживабельно. очередь с рукопожатием на обоих портах. может быть сконфигурирована на использование block RAM так и на обычной логике (в зависимости от установленного атрибута). для указателей на концы очереди использована тривиальная схема кодирования (бинарный код) так что не советую использовать в самолётах, спутниках и в районе экватора. можно только для поиграться. есть две ноги для заглядывания в будущее (может быть полезны для поддержания непрерывного потока данных интерфейсных КА). замеры не делал, потому как там мало управляющей логики. описание: parameterizable queue with a trivial pointer encodings can be implementer eather with on-chip Block RAM or distributed memory, subject to synthesis attribute setting of the stack memory when implemeted with a RAM block adopt the first-word-falls-through policy for zero latency immediate pop provides forward read and write grant signals for smooth operation of FSMs controlling the data-flows on both ports of the channel(queue) блин, други, я чичас чуть не поседел! ВНИМАНИЕ! выложенное фифо содержит ошибку!!! ошибка в неправильном расчёте ширины счётчиков при помощи стандартной функции $clog2() раньше два параметра рассчитывались с помощью самописной функции localparam ptr_width=number_of_bits_for_value_representation(stack_depth-1); localparam cnt_width=number_of_bits_for_value_representation(stack_depth); вот эта функция function int number_of_bits_for_value_representation(input int value); int temp; temp = 2; number_of_bits_for_value_representation = 1; while (temp<=value) begin number_of_bits_for_value_representation = number_of_bits_for_value_representation+1; temp = temp*2; end endfunction перед отправкой на форум я решил выпендриться и заменил расчёт этих параметров на localparam ptr_width=$clog2(stack_depth-1); localparam cnt_width=$clog2(stack_depth); и не проверив работу в симуляторе и не подумав о том, что результат будет уже другой - ширина для cnt_width на один бит меньше, чем положено представляете мои ощущения, когда я в четверг запустил систему, которая была полностью отлажена и которую я не трогал пол года. 2 дня сидел разбирался почему система перестала корректно работать. в общем звиняйте итого. чтобы правильно работало с $clog2 нужно написать вот так localparam ptr_width=$clog2(stack_depth); localparam cnt_width=$clog2(stack_depth+1); попрошу модератора, чтобы исправил исходный пост. файл с изменениями: Ring_Buffer_gnt_forward_fwft_ram_based.txt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 17 апреля, 2011 Опубликовано 17 апреля, 2011 · Жалоба Что-то все про тему забыли... :) у меня нет времени, работы тьма тьмущая Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 28 апреля, 2011 Опубликовано 28 апреля, 2011 · Жалоба В схемах автоматики часто применяются интеграторы,здесь пример параметризуемого знакового интегратора с насыщением.Схема очень простая,пояснений не требуется. src.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 29 апреля, 2011 Опубликовано 29 апреля, 2011 · Жалоба Да-а-а-а-а,не удалось раскрутить общественность.А жаль,умирает тема... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
warrior-2001 0 29 апреля, 2011 Опубликовано 29 апреля, 2011 · Жалоба В качестве подпитки темы сюда можно выложить Synthesis Style Guide для разных компиляторов. У меня есть Precision® Synthesis Style Guide и HDL Coding Styles от Altera. В принципе эти документы доступны всем, но кто их читает ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 2 мая, 2011 Опубликовано 2 мая, 2011 · Жалоба Да-а-а-а-а,не удалось раскрутить общественность.А жаль,умирает тема... у мну например цейтнот последние полгода. скоро разберусь уже с делами и буду вывешивать - есть достаточно разных мелких полезностей. так что никто не забыт и ничто не забыто. просто временно отложено. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 2 мая, 2011 Опубликовано 2 мая, 2011 · Жалоба у мну например цейтнот последние полгода. скоро разберусь уже с делами и буду вывешивать - есть достаточно разных мелких полезностей. так что никто не забыт и ничто не забыто. просто временно отложено. Вот,вот, именно "мелкие полезности" и представляют наибольший интерес,особенно для молодёжи.Я после праздников тоже выложу ещё один блок(вычисление модуля без квадратов и корней). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vpd 0 24 июня, 2011 Опубликовано 24 июня, 2011 · Жалоба Вот еще вариант двухклокового FIFO, на VHDL. library ieee; library ieee; use IEEE.std_logic_1164.all, IEEE.std_logic_unsigned.all, IEEE.std_logic_arith.all; entity dc_fifo is GENERIC ( WIDTHA : integer := 8; WIDTH : integer := 8 ); PORT ( rst : in std_logic; wr_clk: in std_logic; -- write clock wr_ena: in std_logic; -- write clock enable wr_dta: in std_logic_vector(WIDTH-1 downto 0); -- write data rd_clk: in std_logic; -- read clock rd_ena: in std_logic; -- read enable rd_dta: out std_logic_vector(WIDTH-1 downto 0); -- read data rd_empty, rd_full, rd_half : out boolean; -- read side status wr_empty, wr_full, wr_half : out boolean -- write side status ); end dc_fifo; architecture behavior of dc_fifo is constant N : integer := (2**WIDTHA); constant ADR_MAX : integer := (2**WIDTHA)-1; subtype ADDRESS is integer range 0 to ADR_MAX; subtype DATA is std_logic_vector(WIDTH-1 downto 0); type FIFO_RAM is array (0 to ADR_MAX) of DATA; -- binary representation of addersses signal wr_b_adr : ADDRESS; signal rd_b_adr : ADDRESS; -- gray code representation of addresses signal wr_g_adr : ADDRESS; signal rd_g_adr : ADDRESS; -- next write signal signal wr_add : integer range 0 to 1; signal wr_next : ADDRESS; signal ram : FIFO_RAM; attribute syn_ramstyle : string; attribute syn_ramstyle of ram : signal is "no_rw_check"; function bin2gray( a : ADDRESS ) return ADDRESS is variable u, v : std_logic_vector( WIDTHA-1 downto 0 ); variable b : ADDRESS; begin v := conv_std_logic_vector( a, WIDTHA ); u := v xor ('0' & v(WIDTHA-1 downto 1)); b := ADDRESS(conv_integer('0' & u)); return b; end; function gray2bin( a : ADDRESS ) return ADDRESS is variable u, v : std_logic_vector( WIDTHA-1 downto 0 ); variable b : ADDRESS; variable x : std_logic; begin v := conv_std_logic_vector( a, WIDTHA ); for i in u'range loop x := '0'; for j in v'range loop if (j>=i) then x := x xor v(j); end if; end loop; u(i) := x; end loop; b := ADDRESS(conv_integer('0' & u)); return b; end; function fifo_size( w, r : ADDRESS ) return ADDRESS is constant N : integer := (2**WIDTHA); variable b : ADDRESS; begin b := (N + w - r) mod N; return b; end; begin wr_add <= 1 when wr_ena='1' else 0; wr_next <= ( wr_b_adr + wr_add ) mod N; WRITE_PART:process(rst,wr_clk) begin if rst='0' then wr_b_adr <= 0; wr_g_adr <= bin2gray( 0 ); wr_empty <= true; wr_full <= false; wr_half <= false; elsif rising_edge(wr_clk) then -- fix values. Needed for better inferring RAM block wr_b_adr <= wr_next; wr_g_adr <= bin2gray( wr_next ); wr_empty <= fifo_size( wr_b_adr, gray2bin(rd_g_adr) ) < 2; wr_full <= fifo_size( wr_b_adr, gray2bin(rd_g_adr) ) >= N-4; wr_half <= fifo_size( wr_b_adr, gray2bin(rd_g_adr) ) >= N/2; end if; end process; RAM_STORE:process(wr_clk) begin -- perform write, no reset dependency if rising_edge(wr_clk) then if wr_ena='1' then ram(wr_b_adr) <= wr_dta; end if; end if; end process; READ_PART:process(rst,rd_clk) begin if rst='0' then rd_b_adr <= 0; rd_g_adr <= bin2gray( 0 ); rd_empty <= true; rd_full <= false; rd_half <= false; elsif rising_edge(rd_clk) then if rd_ena='1' then rd_b_adr <= (rd_b_adr+1) mod N; rd_g_adr <= bin2gray( (rd_b_adr+1) mod N ); end if; -- fifo status on the reader part rd_empty <= fifo_size( gray2bin(wr_g_adr), rd_b_adr ) <= conv_integer(rd_ena); rd_full <= fifo_size( gray2bin(wr_g_adr), rd_b_adr ) >= N-2; rd_half <= fifo_size( gray2bin(wr_g_adr), rd_b_adr ) >= N/2; end if; end process; RAM_PEEK:process(rd_clk) begin -- read register for dual-port RAM inferring if rising_edge(rd_clk) then if rd_ena='1' then rd_dta <= ram(rd_b_adr); end if; end if; end process; end behavior; Где-то еще развлекался с преобразованием ширины шины на входе и выходе. Идея такая же как у базового FIFO, только запись или чтение добавляют к одному из счетчиков не 1, а 2^n. Например, Шина PCI имеет разрядность 32 бита, а кор заточен под 8. Можно делать регистры перепаковки снаружи обычного FIFO, а можно просто память читать другой ширины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 25 июня, 2011 Опубликовано 25 июня, 2011 · Жалоба Вот еще вариант двухклокового FIFO, на VHDL. красиво написано, но напрягают несколько моментов : 1. полное отсутствие синхронизаторов указателей wr_clk/rd_clk 2. сомнительная производительность цепей вида fifo_size( gray2bin(wr_g_adr), rd_b_adr ) <= conv_integer(rd_ena) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vpd 0 25 июня, 2011 Опубликовано 25 июня, 2011 (изменено) · Жалоба красиво написано, но напрягают несколько моментов 1. не понял, о чем речь :) 2. вообще производительность получалась вполне приличная, во всяком случае она примерно соответствовала производительности встроенной памяти, на которой и строилось FIFO. Генерацию статусов можно при желании и поменять, увеличив задержки их формирования и подняв частотку. Например, fifo_size( gray2bin(wr_g_adr), rd_b_adr ) <= conv_integer(rd_ena) можно заменить на wr_b_adr <= gray2bin(wr_g_adr); rd_empty <= fifo_size( wr_b_adr, rd_b_adr ) <= conv_integer(rd_ena) Я вообще в этом коде делал упор на то, чтобы он синтезировался (автогенерировался блок встроенной памяти) под подобные любые семейства для Альтеры и Xilinx (Spartan-Cyclone, Virtex-Stratix). Проблема в том, что возможности блока памяти, формально выводимого из описания на VHDL, заметно урезаны по сравнению с вставкой библиотечного блока памяти, возможности которого зависят от семейства и требуют правки кода при смене платформы. А вообще, добавлю, что: Преждевременная оптимизация — корень всех зол Изменено 25 июня, 2011 пользователем Hoodwin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosu-art 0 12 июля, 2011 Опубликовано 12 июля, 2011 · Жалоба А не просветите... зачем в ФИФО используется код Грея? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vpd 0 13 июля, 2011 Опубликовано 13 июля, 2011 · Жалоба Если частоты независимы, то при переводе массива битов из одного частотного домена в другой возможны сильные искажения, поскольку изменения отдельных битов могут зафиксироваться в новом домене в разных тактах. Ну, к примеру, в первом домене счетчик идет по порядку 01111B, 10000B, а во втором домене может быть 01111B, 10100B, 10000B. То есть, задержка бита 2 такова, что он опаздывает на один такт, но не всегда, а лишь иногда, при неблагоприятных фазах двух частот. А код Грея замечателен тем, что последовательные значения счетчика отличаются изменением только одного бита. Поэтому при переводе величины в коде Грея на новую частоту фазовые сдвиги тактовых сигналов не могут привести к ошибкам, возможно либо новое, либо старое значение величины после возврата к обычному бинарному представлению. В итоге такое фифо может работать при любых соотношениях частот. Для ФИФО, работающего на одной частоте или на кратных частотах, код Грея не нужен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aosp 0 22 ноября, 2011 Опубликовано 22 ноября, 2011 · Жалоба Итак господа, давайте попробуем достичь результата. Выкладывать алгоритмы работы различных очередей (устройств со сложным поведением) мне кажется смысла особого нет. Есть принципиальные вещи в способах их построения, и одной из таких вещей является компонент перехода данных из одного частотного домена в другой. Давайте попробуем формализовать эту процедуру и зафиксировать результат в виде кода на VERILOG. Постановка задачи: - реализовать мост для данных (разрядность 1 бит) из одного частотного домена в другой. - фазы частот разные, частоты отличаются в разы (например 125 МГц и 20 МГц) - время перехода Тpd - минимальное. ------- -----------------+ +---------------------------------- импульс в домене 125МГц (один такт) <-----------> Тpd -------------------------- -------------------------------+ +-------- импульс в домене 20МГц (один такт) Шапка модуля: module xdomen ( input clk1, input din, input clk2, output dout ); <здесь находится коД....> // предлагаем свои решения.... endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 22 ноября, 2011 Опубликовано 22 ноября, 2011 · Жалоба Постановка задачи: - реализовать мост для данных (разрядность 1 бит) из одного частотного домена в другой. - фазы частот разные, частоты отличаются в разы (например 125 МГц и 20 МГц) - время перехода Тpd - минимальное. toggle_synchronizer.v pulse_synchronizer.v Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
stu 0 6 декабря, 2011 Опубликовано 6 декабря, 2011 · Жалоба не нашел куда написать, а новой темы....... где-то спрашивал, но ответа не было. в общем, есть для примера код: DFFE ff0 (.d(Din[0]), .ena(ena), .clk(clk_GN), .q(iDin[0])); DFFE ff1 (.d(Din[1]), .ena(ena), .clk(clk_GN), .q(iDin[1])); DFFE ff2 (.d(Din[2]), .ena(ena), .clk(clk_GN), .q(iDin[2])); DFFE ff3 (.d(Din[3]), .ena(ena), .clk(clk_GN), .q(iDin[3])); На AHDL можно написать: ff[3..0]: dffe; ff.(d, ena, clk, q) = (Din[3..0], ena, clk_GN, iDin[3..0]); На SV никак в одну строчку не укоротить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться