SM 0 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба Как заставить DC проанализировать один регистр-защелку (с асинхронным enable) как комбинаторный элемент? Суть в том, что он стоит на пути шины данных от входного пада до внутренних регистров. Он в нормальном режиме всегда разрешен "насквозь". Мне надо обконстрейнить сетап по этой шине данных - и соответственно как-то сказать DC, что на этой самой гребаной защелке путь не окончен, и ее задержка D->Q при активном E есть часть пути. Как это сделать? Я что-то втупил не на шутку... Разрешение на эту защелку идет вообще снаружи (с аналоговой части, там формирователь импульсов, это изврат для low power), и оно не объявлено клоком. ЗЫ в проекте еще куча защелок, так вот мне надо такое поведение сделать для одной. Остальные честные - управляются через gated clock. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Михаил А 0 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба не используйте в проекте latch-и это закон. Нет причин чтобы их использовать, площадь - это в случае если много регистровых файлов - тогда да. Но в случае управляющей логики - flip-flop ничем не хуже. Если не можете его убрать в принципе, то другого пути, кроме как залезть в lib файл этого latch-a и убрать свойство clock с пина G который и является клоком. в принципе наверное есть какие-то стандартные методы - у вас sold есть - руководство по синтезу ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба не используйте в проекте latch-и это закон. Нет причин чтобы их использовать, площадь - это в случае если много регистровых файлов - тогда да. Не могу не использовать. Площадь - центы денег :), один латч чуть больше пол-триггера. Далее - регистровый файл (он же внутреннее ОЗУ) построен на асинхронной двухпортовке (опять из соображения min_area) - так что формирователи импульсов записи все равно есть. Регистры внешних устройств находятся в том-же адресном пространстве, так что их совершенно безопасно сделать на латчах. Еще один забытый важный фактор - потребление. Латч имеет и меньшие утечки, и меньший жрач в динамике. Это для меня на втором месте после area. Ну а частота - на третьем, тем более что ее ограничивает внешняя ПЗУ. Теперь - именно в этом месте латч просто необходим. Поясню - это микропроцессор, который может работать от двух клоков - высокочастотного и низкочастотного. Программа всегда исполняется из внешнего ПЗУ. При работе на высокой частоте этот латч находится в хронически разрешенном состоянии, пропуская данные насквозь, внешняя ПЗУ все время выбрана. Итого я получаю 12 мгц (и мипс) при 75-нс ПЗУ. При работе от низкочастотного включается в работу формирователь короткого (150 нс) импульса по спаду клока. При этом адрес на ПЗУ выставляется по фронту клока, а сама ПЗУ выбирается на те самые 150 нс по спаду. В это же время тот самый латч запоминает считанные данные, после чего ПЗУ отключается, а даные остаются, принимаясь ядром в буфер предвыборки по следующему фронту. Это дает громадное уменьшение тока потребления внешней ПЗУхой (150 нс выборки при 32768 гц тактовой - скважность сами посчитайте, если интересно) . Так вот - констрейн-то мне нужен в режиме "открытого" латча, то есть для ВЧ-клока. Кстати, в предыдущей версии этого процессора такой блок работает на ура, но я там констрейнил отдельно путь до латча, и отдельно от латча. Не хочу больше так криво констрейнить, ибо путь там серьезно усложнился, как и весь проц целиком. :) Спасибо за идею покопать .lib, в принципе не проблема сделать копию латча с убранным свойством клока, и их насильно поставить под "dont_touch". Ну и скопировать еще в остальных местах, в LVS-нетлисте, в GDSе, и т.д. До этого сам не догадался. Но, хотелось узнать есть ли нормальный способ. Типа "set_что_нибудь мой_модуль/мой_латч" Все таки латч разрешенный есть буфер, и почему бы его не уметь анализировать таким образом. SOLD есть, сижу вот перекапываю. Начинал с help/man. Пока глухо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 6 июля, 2006 Опубликовано 6 июля, 2006 · Жалоба YESSS! Проблема решена красивым путем. В .lib добавил в описание латчей: mode_definition(latch) { mode_value(transparent) { when : "E"; sdf_cond : "E == 1"; } mode_value(trigger) { when : "!E"; sdf_cond : "E == 0"; } } и расставил в либе в timig {} свойства mode. Для пути D->Q transparent, остальные - холды, сетапы на trigger. Далее в скрипте указал set_mode transparent [get_cells fetch_dbus_latch*] После чего все было синтезировано и проанализировано как мной задумано. ЗЫ, для Михаил А, не было на пине "E" свойства clock в либе. Наверное оно автоматом ставится или от группы "latch{}", или из наличия таймингов типа setup/hold. Хотя это догадки. ЗЗЫ А все таки гады эти вендоры, либра-виза. Могли бы и сами это продумать. А тут сиди-копай мануалы на library compiler. Хорошо хоть есть опыт изготовления самодельных IO-падов, копать не долго пришлось и знал структуру .lib Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 6 июля, 2006 Опубликовано 6 июля, 2006 · Жалоба Еще засада :) Он почему-то при compile сбрасывал у некоторых разрядов этой защелки признак "mode". Пришлось еще set_register_type сказать... Воистину пути синтезатора неисповедимы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Михаил А 0 6 июля, 2006 Опубликовано 6 июля, 2006 · Жалоба а чта же там на пине Е стояло ? что это клок он распознает по этому признаку - clock или по функции описанной на пине Q - выходе latch-a ну и разумеется - убрав clock свойство или изменив функцию latch-a в него надо было просто вставить функцию из ячейки AND можно сюда вклюнуть header этого lacth-a и внизу описание функции на пине Q мда - большая экономия площади на 10 триггерах, замененых latch- ем когда вот так - ограничены внешним протоколом, то да - приходится ставить, иначе это гимор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 6 июля, 2006 Опубликовано 6 июля, 2006 · Жалоба а чта же там на пине Е стояло ? что это клок он распознает по этому признаку - clock или по функции описанной на пине Q - выходе latch-a ну и разумеется - убрав clock свойство или изменив функцию latch-a в него надо было просто вставить функцию из ячейки AND Да в том то и дело, что ничего там не стояло. Там было описание ф-ции в виде групы latch {}, тайминги, потребление. И все. Для того, чтобы он "E" перестал анализировать как клок оказалось достаточно убрать тайминги типа "setup_falling" и "hold_falling". Что я и сделал, введя свойство "mode" и группы таймингов, зависящих от "mode". можно сюда вклюнуть header этого lacth-a и внизу описание функции на пине Q пжалста, вот одна из них. Прям целиком из либы в нарушение NDA :). Правда ужо с добавлением моей mode_definition. cell(lanhq1) { mode_definition(latch) { mode_value(transparent) {} mode_value(trigger) {} } cell_footprint : lanhq_4; area : 3.66; routing_track(metal1){ tracks : 0; total_track_area : 0; } routing_track(metal2){ tracks : 11; total_track_area : 1.57; } routing_track(metal3){ tracks : 9; total_track_area : 1.83; } routing_track(metal4){ tracks : 8; total_track_area : 1.90; } scaling_factors : lanhq1_factors; cell_leakage_power : 516.559; latch (IQ,IQN){ enable : "E"; data_in : "D"; } internal_power(power_inputs_1) { related_input : "E"; values( " 0.174 0.182 0.258"); } pin(E) { direction : input; capacitance : 0.006; fanout_load : 1; min_pulse_width_high : 0.340; } internal_power(power_inputs_1) { related_input : "D"; values( " 0.0745 0.0900 0.182"); } pin(D) { direction : input; capacitance : 0.006; fanout_load : 1; timing() { mode(latch,trigger); timing_type : setup_falling; related_pin : "E"; fall_constraint(vio_0_5_5) { values( " 0.200, 0.300, 0.410, 0.620, 0.820",\ " 0.090, 0.200, 0.320, 0.530, 0.710",\ " 0.010, 0.100, 0.220, 0.430, 0.620",\ " -0.150, -0.050, 0.060, 0.260, 0.450",\ " -0.290, -0.200, -0.100, 0.120, 0.300"); } rise_constraint(vio_0_5_5) { values( " 0.040, 0.080, 0.130, 0.170, 0.180",\ " -0.060, -0.020, 0.030, 0.070, 0.080",\ " -0.160, -0.130, -0.090, -0.050, -0.030",\ " -0.360, -0.320, -0.280, -0.240, -0.230",\ " -0.500, -0.470, -0.460, -0.410, -0.400"); } } timing() { mode(latch,trigger); timing_type : hold_falling; related_pin : "E"; fall_constraint(vio_0_5_5) { values( " -0.180, -0.280, -0.380, -0.580, -0.750",\ " -0.080, -0.190, -0.300, -0.480, -0.650",\ " 0.010, -0.080, -0.200, -0.390, -0.560",\ " 0.170, 0.070, -0.040, -0.220, -0.390",\ " 0.320, 0.210, 0.110, -0.080, -0.240"); } rise_constraint(vio_0_5_5) { values( " -0.020, -0.070, -0.120, -0.150, -0.150",\ " 0.080, 0.030, -0.010, -0.050, -0.040",\ " 0.180, 0.140, 0.100, 0.070, 0.060",\ " 0.380, 0.330, 0.290, 0.260, 0.260",\ " 0.540, 0.490, 0.470, 0.430, 0.430"); } } } internal_power(power_outputs_16) { /* average switching power [in pJ] for pin 'Q' */ related_outputs : "Q"; related_inputs : "D E"; values( " 0.336, 0.325, 0.316, 0.311, 0.306",\ " 0.331, 0.318, 0.309, 0.304, 0.289",\ " 0.341, 0.325, 0.312, 0.306, 0.308"); } pin(Q) { direction : output; max_capacitance : 0.300; max_fanout : 30; max_transition : 3.0; function : "IQ"; timing() { mode(latch,transparent); timing_type : rising_edge; related_pin : "E"; cell_rise(del_16_3_5) { values( " 0.570, 0.660, 0.810, 1.050, 1.510",\ " 0.640, 0.740, 0.890, 1.120, 1.590",\ " 0.610, 0.710, 0.860, 1.090, 1.560"); } rise_transition(del_16_3_5) { values( " 0.220, 0.390, 0.700, 1.240, 2.330",\ " 0.220, 0.390, 0.700, 1.240, 2.330",\ " 0.220, 0.390, 0.700, 1.240, 2.330"); } cell_fall(del_16_3_5) { values( " 0.510, 0.600, 0.730, 0.890, 1.160",\ " 0.590, 0.680, 0.800, 0.970, 1.240",\ " 0.570, 0.650, 0.780, 0.940, 1.210"); } fall_transition(del_16_3_5) { values( " 0.220, 0.320, 0.490, 0.730, 1.200",\ " 0.210, 0.320, 0.500, 0.730, 1.200",\ " 0.220, 0.330, 0.490, 0.730, 1.200"); } } timing() { mode(latch,transparent); related_pin : "D"; timing_sense : positive_unate; cell_fall(del_16_3_5) { values( " 0.390, 0.480, 0.600, 0.760, 1.030",\ " 0.600, 0.680, 0.810, 0.970, 1.240",\ " 0.960, 1.060, 1.190, 1.360, 1.630"); } fall_transition(del_16_3_5) { values( " 0.220, 0.320, 0.500, 0.730, 1.200",\ " 0.220, 0.330, 0.500, 0.730, 1.200",\ " 0.260, 0.370, 0.540, 0.770, 1.220"); } cell_rise(del_16_3_5) { values( " 0.360, 0.460, 0.610, 0.840, 1.310",\ " 0.450, 0.550, 0.700, 0.930, 1.400",\ " 0.480, 0.580, 0.740, 0.970, 1.430"); } rise_transition(del_16_3_5) { values( " 0.220, 0.390, 0.700, 1.240, 2.330",\ " 0.220, 0.400, 0.700, 1.240, 2.330",\ " 0.250, 0.420, 0.730, 1.250, 2.330"); } } } } мда - большая экономия площади на 10 триггерах, замененых latch- ем Сорри, Вы навреное не так поняли. В данном конкретном месте латч необходим. А в остальных местах - это не 10 триггеров. Это по 30-40 триггеров на каждый блок, подключенный к ядру. Причем не создающих никаких проблем при замене на латчи. В реальных цифрах это примерно 2500 NAND-ячеек по всей микрухе. Вместо которых я могу неплохой операционник например всунуть. И не один. Или еще что-нить полезное. Для сравнения умножитель 17х17 бит 2980 занимает при моих таймингах. Сорри, но каждый цент, сэкономленный на площади - мой. И просто так, ради уменьшения геморроя при разработке, терять его я не намерен. И, даже, пусть первая итерация не складется (тьфу-тьфу не дай бог). Но все равно, оно в моем случае того стоит. P.S. А что Вы имели в виду под "ф-цией на пине Q"? Если .lib-описание, то это "latch" :) А если что в проекте с ним делается, то какая разница? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться