Jump to content

    

des00

Модераторы
  • Content Count

    7654
  • Joined

  • Last visited

Everything posted by des00


  1. Цитата(MAZZI @ Jul 1 2005, 09:47)то что ты вкратце описал, не очень красивое решение, т.к. все равно обращаешься на компоненты памяти, или я не прав? Да и было бы интереснее если бы ты показал на примере <== что ты имеешь ввиду правда на ВХДЛ но смысл бумаю будет понятен Кодlibrary IEEE; use IEEE.std_logic_1164.all;     use IEEE.std_logic_arith.all;     use IEEE.std_logic_unsigned.all; library WORK; use WORK.define_pkg.all; entity RAM_16_DWC_Dev is    generic (WIDTH : integer := 16);    port        (        in_clock      : in std_logic;        in_reset_b    : in std_logic;        in_wr_data    : in std_logic_vector(4*WIDTH-1 downto 0);                      in_wr_strobe  : in std_logic;  in_wr_addr   : in std_logic_vector(3 downto 0);        in_rd_addr   : in std_logic_vector(5 downto 0);        out_rd_data   : out std_logic_vector(WIDTH-1 downto 0)        ); end entity RAM_16_DWC_Dev; architecture RAM_16_DWC_Dev of RAM_16_DWC_Dev is        type RAM_16 is array (0 to 7) of std_logic_vector(4*WIDTH-1 downto 0);    signal mem : RAM_16;    attribute RAM_STYLE of mem : signal is "distributed";     attribute SYN_RAMSTYLE of mem : signal is "select_ram";     begin     mem_read_proc :     process(in_clock) is    variable reg0, reg1, reg2, reg3 : std_logic_vector(WIDTH-1 downto 0);     variable mem_data : std_logic_vector(4*WIDTH-1 downto 0);     begin        if (rising_edge(in_clock)) then      if (in_reset_b = '0') then          out_rd_data <= (others => '0');        else    mem_data := mem(conv_integer(in_rd_addr(5 downto 2)));      demux_data(mem_data, reg0, reg1, reg2, reg3);    case (in_rd_addr(1 downto 0)) is              when "00" => out_rd_data <= reg0;              when "01" => out_rd_data <= reg1;              when "10" => out_rd_data <= reg2;              when "11" => out_rd_data <= reg3;        when others => null;    end case;      end if;        end if;    end process mem_read_proc;        mem_write_proc :     process(in_clock) is    begin                        if (rising_edge(in_clock)) then            if (in_wr_strobe = '1') then                mem(conv_integer(in_wr_addr)) <= in_wr_data;            end if;        end if;    end process mem_write_proc;        end architecture RAM_16_DWC_Dev; насчет корректности твоего описания Цитатаreg R_tmp_mem [(WIDTH_WR_DATA*DEPTH_WR-1):0]; reg [(WIDTH_RD_ADDR-1): 0] R_rd_addr; вот здесь ты объявляешь не память а регистр. А тебе нужна именно память, а не набор регистров. Цитатаreg R_tmp_mem [(1*4096-1):0]; reg [(9-1): 0] R_rd_addr; // 9 разрядный счетчик (2**9=512) по WIDTH_RD_DATA = 8 получается, что бит я покрываю 512*8=4096 при чтении, всё корректно. А теперь скажи как ты будешь адресовать 8 ми битные слова ? Мы разговариваем про разные вещи, память это двумерный массив. У памяти может быть 1-2 порта чтения записи, если же их больше, то это приведет к памяти на регистрах. Если у тебя их много то ...... а если нет ??
  2. Цитата(MAZZI @ Jul 1 2005, 08:58)Возможно ты прав, возможно я и ленивый, если ты ставишь вопрос таким образом, то: 1) помоги найди некорректность в моем описании на Verilog выложенное выше. 2) расскажи ещё раз принцип описания на языке, я его что-то не увидел здесь. мне бежать надо по этому вкратце 1. порт записи 32 бита, адрес 8 бит. порт чтения 16 бит адресс 9 бит пишем просто по входным адресам, когда читаем первые 8 бит это адрес памяти, младший бит на выходной мультиплексор. 2. если наоборотт, то мультиплексируем сигнал разрешения записи. младшим битом а старшие 8 бит на адресс. В твоем описании (подробно не смотрел) симплифай ругаеться, т.к. у тебя есть массив пр.32 по 32 бита а ты почему то решил из него сделать 64 на 16 бит, адреса не совпадають удачи
  3. Цитата(MAZZI @ Jul 1 2005, 08:43)Как мы все дружно решаем данную ситуацию, давайте, парни, поднапряжемся, кто-нибудь найдет решение . Ты скажи русским/английским языком что тебе надо ?? Если память сконфигуровать то читай апноты или руками конфигури. Если описать на языке то принцип тебе расказали, или ты хочешь что бы тебе еще и код с коментариями запостили ?? ну ты ленивый
  4. Цитата(MAZZI @ Jul 1 2005, 08:24)Это делает код более мобильным и переносимым на другие ПЛИС, ASIC. Ну во первых это боольшой вопрос, т.к. : 1. Вам "повезло" с семейством, т.к. разная ширина шин у кмпонента это "фишка" данного семества и на "другие" так просто не переноситься. 2. Если вы хотите универсальности в ручную мапте адреса и демультиплексируете потоки.(как и сделано в компоненте). Но вот мне не удалось сказать синтезатору ИСЕ и симплифай (даже с контрейнами) что то что я описал на языке должно быть не блоком памяти с мультеплексором, а одним компонентом. А так это описываеться элементарно, а вот синтезируеться ......
  5. Цитата(MAZZI @ Jul 1 2005, 07:35)Если это обсуждалось (в чем я сильно сомневаюсь), дайте ссылочку, пожалуйста, то же и по appnotes, использовал для примера CORE Generator, он сослался на библиотечный элемент BLKMEMDP_V6_1.v, слишком все тяжело описано в нем, разобраться не могу, сам придумал реализацию, по крайней мере в моделе всё как и задумывалось: <================================================== /*  ОБЪЯВЛЕНИЕ МОДУЛЯ  */ module C_DPINDEP_RAM /*----------------------------------------------------------------------------- *  Объявление параметров: */ #( parameter WIDTH_WR_DATA = 1, WIDTH_WR_ADDR = 12, DEPTH_WR = (1<<WIDTH_WR_ADDR), WIDTH_RD_DATA = 8, WIDTH_RD_ADDR = 9 ) /*----------------------------------------------------------------------------- * Объявление портов: */ ( // порт записи input i_WR_CLK, // тактовый импульс записи i_WR_EN, // строб разрешения записи input [(WIDTH_WR_DATA-1): 0] i_WR_DATA,// шина данных записи input [(WIDTH_WR_ADDR-1): 0] i_WR_ADDR,// адресная шина записи // порт чтения input i_RD_CLK, // тактовый импульс чтения input [(WIDTH_RD_ADDR-1): 0] i_RD_ADDR, // адресная шина чтения output reg [(WIDTH_RD_DATA-1): 0] o_RD_DATA // шина данных чтения ); /*----------------------------------------------------------------------------- * Объявление сигналов: */ reg R_tmp_mem [(WIDTH_WR_DATA*DEPTH_WR-1):0]; reg [(WIDTH_RD_ADDR-1): 0] R_rd_addr; integer j, k; /* synthesis translate_off */ integer i; initial begin for (i = 0; i < WIDTH_WR_DATA*DEPTH_WR; i= i + 1) R_tmp_mem[i] <= 1'b0; R_rd_addr <= {WIDTH_RD_ADDR{1'b0}}; end /* synthesis translate_on */ /*----------------------------------------------------------------------------- * Основной код: */ always @(posedge i_WR_CLK) begin if (i_WR_EN) for (j = 0; j < WIDTH_WR_DATA; j = j + 1) R_tmp_mem[(i_WR_ADDR * WIDTH_WR_DATA) + j] <= i_WR_DATA[j]; end always @(posedge i_RD_CLK) begin R_rd_addr <= i_RD_ADDR; end always @*//(posedge i_RD_CLK)  <=== пробовал и в комментарии и без for (k = 0; k < WIDTH_RD_DATA; k = k + 1) o_RD_DATA[k] = R_tmp_mem[(R_rd_addr * WIDTH_RD_DATA) + k]; endmodule <================================================== только вот беда, синтезатор (Symplify_pro8.1) не берет это описание как БЛОЧНУЮ ПАМЯТЬ, и пишет: Could not implement Block RAM. Is the read address registered using the same clock as the RAM? Как правильно описать такую модель для Блочной памяти? Зачем core generator !!!!!!! XAPP205 - Data-Width Conversion FIFOs Using the Virtex Block SelectRAM Memory XAPP261 - Data-Width Conversion FIFOs Using the Virtex-II Block RAM Memory XAPP258 - FIFOs Using Virtex-II Block RAM и т.д. просто берем компоненит RAMB_16 и конфигурим его ручками Код-- Component declaration of the "ramb16(ramb16_v)" unit defined in     -- file: "./src/unisim_vital.vhd"     component ramb16     generic(  DOA_REG : INTEGER := 0;  DOB_REG : INTEGER := 0; INVERT_CLK_DOA_REG : BOOLEAN := false;  INVERT_CLK_DOB_REG : BOOLEAN := false;  RAM_EXTENSION_A : STRING := "NONE";  RAM_EXTENSION_B : STRING := "NONE";  READ_WIDTH_A : INTEGER := 0;  READ_WIDTH_B : INTEGER := 0;  SIM_COLLISION_CHECK : STRING := "ALL";  SRVAL_A : BIT_VECTOR := X"000000000";  SRVAL_B : BIT_VECTOR := X"000000000";  WRITE_MODE_A : STRING := "WRITE_FIRST";  WRITE_MODE_B : STRING := "WRITE_FIRST";  WRITE_WIDTH_A : INTEGER := 0;  WRITE_WIDTH_B : INTEGER := 0);     port(  CASCADEOUTA : out std_ulogic;  CASCADEOUTB : out std_ulogic;  DOA : out std_logic_vector(31 downto 0);  DOB : out std_logic_vector(31 downto 0);  DOPA : out std_logic_vector(3 downto 0);  DOPB : out std_logic_vector(3 downto 0);  ADDRA : in std_logic_vector(14 downto 0);  ADDRB : in std_logic_vector(14 downto 0);  CASCADEINA : in std_ulogic;  CASCADEINB : in std_ulogic;  CLKA : in std_ulogic;  CLKB : in std_ulogic;  DIA : in std_logic_vector(31 downto 0);  DIB : in std_logic_vector(31 downto 0);  DIPA : in std_logic_vector(3 downto 0);  DIPB : in std_logic_vector(3 downto 0);  ENA : in std_ulogic;  ENB : in std_ulogic;  REGCEA : in std_ulogic;  REGCEB : in std_ulogic;  SSRA : in std_ulogic;  SSRB : in std_ulogic;  WEA : in std_logic_vector(3 downto 0);  WEB : in std_logic_vector(3 downto 0));     end component;     for all: ramb16 use entity unisim.ramb16(ramb16_v); если уже совсем не в моготу то пользуем уже готовый компоненты библитеки унисим типа RAMB_X_X. Все это описанно в Lib Guide
  6. Цитата(MAZZI @ Jul 1 2005, 04:32)Интересен пример описания блочной памяти, где были бы два независимых конфигурируемых порта по записи и по чтению, с такой синтезируемой моделью можно легко будет делать преобразователи из последовательного в параллельный код, минуя сдвиговые регистры (сейчас я с ними делаю). Какие есть решения по данной реализации на Verilog (VHDL), чтобы ещё и понятно было ? выкладывайте. У ксайлинсков около 10 апнот на эту тему!!!!!!!! ищите по BLOCK RAM DATA WIDTH CONVERTION FIFO
  7. Цитата(Serega Doc @ Jun 30 2005, 03:09)Тогда мне надо приоритетный декодер с контроллером прерываний. У меня один процес существует всегда и имет нивысший приоритет обращения к памяти. А другие могут быть а могут и не быть. Где взять доки и теорию. А то снова модифицировать конечный автомат а затем тестировать блок нет никакого желания. наткнулся вчера, посмотрите может что поможет xapp535 "High Performance Multi-Port Memory Controller"
  8. Цитата(Serega Doc @ Jun 30 2005, 02:38)ЦитатаНе совсем понял вам нужен контроллер прерываний или приоритетный декодер ? А в чем разница? Хммм ИМХО задача контроллера прерываний среагировать на конкретное событие и сообщить об этм системе верхней иерархии и все. А задача приртетного декодера в вашем случае будет более точным назвать его многоканальным контроллером, развести одну память на несколько процессов/блоков. В котором доступ к разделяемуму ресурсу (памяти) определяеться приоритетом запроса.
  9. Цитата(evgforum @ Jun 30 2005, 01:03)Цитата(vetal @ Jun 29 2005, 12:02)В окне Flow Configuration Settings установить: 1. HDL Synthesyis   Synplicity Synplify (Pro) 7.x.   Location  - путь к директории bin synplify. 2. Iplementation   Actel Designer v5.x   Location - путь к директории bin Designer(Libero). 3. Family - выбрать нужное семейство микросхем. И далее локальные настройки пунктов 1 и 2. В пункте 1: Устанавливаю путь C:\Libero\Synplify\Synplify_771B\bin А он мне красной строкой пишет, что synplify.exe не найден в каталоге C:\Libero\Synplify\Synplify_771\bin Причем отличаются пути всего лишь одной буквой В после 771 Ну я переписал каталог Synplify по новому пути - все вызывается и компилится... Может по-нормальному можно сделать? может быть все дело в переменных окружения ?
  10. Цитата(Serega Doc @ Jun 30 2005, 00:50)Существует отлаженый блок работы со SDRAM памятью выполняющий потоковое копирование данных внутри этой памяти и на 1 приемник данных Необходимо добавить еще 1-3 приемников для выполнения дополнительных операций с данными из память. Как их добавить так чтобы можно было указывать приоритет работы с памятью каждого из дополнительных приемников. Отлаженый блок работает по строгому циклу - период которого изменять нельзя. Подскажите где можно почитать про основы построения контроллера прерываний или где взять корку? Не совсем понял вам нужен контроллер прерываний или приоритетный декодер ?
  11. Цитата(DLR @ Jun 29 2005, 01:12)Посавил в один - то же самое!!! а можно тогда весь код ? а не его кусок
  12. Цитата(DLR @ Jun 28 2005, 23:35)Сброс то есть но в другом процессе!, я его просто не показал. Именно после этого сброса, по заднему фронту на выходе FIFO образуется неопределенное состояние! Это как так ?? назначение в одном процессе а сброс в другом ?? тогда ясно почему непределенное состояние переделать на 1 процесс
  13. Цитата(Gate @ Jun 27 2005, 07:29)Если в коде процесса нет других присваиваний (до или после приведенного автором оператора IF) для DOA и DOB, то код автора будет всегда приводить к появлению латчей. Я предполагал,  что если проблема в этих сигналах, то автор достаточно сообразителен, чтобы привести весь текст, где эти сигналы меняются. Иначе нечего и обсуждать хмм а если то что он привел у него стоит в process(clock) is begin if (rising_edge (clock)) then ......... то то же будут латчи ? или все таки тригеры ?
  14. Цитата(Gate @ Jun 27 2005, 06:37)При таком описании на DOA и DOB синтезатор будет ставить латчи, что плохо. Надо писать так: IF DIR = 0 then   DIN  <= DIA;   WR  <= IA;   DOB <= DO;   DOA <= 0; -- или что-то другое   RD  <= IB; else   DIN <= DIB;   WR  <= IB;   DOA <= DO;   DOB <= 0; -- или что-то другое   RD  <= IA; end if; или еще проще DOA <= DO; DOB <= DO; IF DIR = 0 then   DIN  <= DIA;   WR  <= IA;   RD  <= IB; else   DIN <= DIB;   WR  <= IB;   RD  <= IA; end if; т.е. 2 шины DOA и DOB на самом деле не нужны. Ну не факт!!! Автор же не указал какой у него процес ? он просто привел часть кода, может быть у него регистровые выходы ?
  15. Цитата(Serega Doc @ Jun 24 2005, 00:07)Сейчас нужны тайминги. А какой же надо комп? У меня P4 2.4GHz 512 ОЗУ ИМХО когда я дойду до полного синтеза всего проекта я постарвюсь запускать его на 4х головом оптероне с 2 - 4 гигами озу. Или просить у начальтсва АМД64 3000+ с 2 гигами )
  16. Цитата(Serega Doc @ Jun 23 2005, 09:23)Если пользую Synplify + Quartus то помоему синтез и роутинг происходят быстрее чем если пользовать один Quartus. Как увеличить скорость синтеза у Quartus Какая вам нужна симуляция ? если только тайминг, то ИМХО больше ОЗУ и проц помощнее, или под линух переходить. если функционал то можно в квартусе не делать роутинг, это будет быстрее.
  17. Цитата(ReAl @ Jun 23 2005, 12:08)Попробуй разбить автомат на два. "автомат перебора адресов" и "автомат вычислений", а контроллер памяти - между ними. Т.е. "автомат перебора" выдаёт на контроллер памяти начальные адреса и запускает его. "контроллер" читает пакет и выдаёт на "автомат вычислений" строб начала пакета и стробы сопровождения данных. "автомат вычислений" делает своё дело и дальше пропихивает результат. спасибо за ответ. именно по этому пути я и пошел правда искал этот путь несколько дней(у всех бывает первый раз, в первый класс)
  18. Задача: Есть блок памяти с определенной задержкой считывания(положим 3 такта) Из него нужно прочитать пакеты по 4 слова, но начальный адресс пакета может быть любым. (т.е. например читаем с 1 го адреса 4 слова, затем с 15го 4 слова и т.д.). Есть блок арифметики который работает с этими словами, реализованный на основе конечного автомата. Теперь сам вопрос. Если я делаю "контроллер" этой памяти, в который пишу: начальный адрес, длину пакета(запас на будующее) и жду когда он выдаст сигнал валидности считаных данных, по которому идут переходы конечного автомата ариметического блока, то получаеться что если я выставляю параметры для "контроллера" памяти в том состоянии КА в котором нахожусь, то я теряю на каждой загрузке контроллера памяти 3 такта, но при этом получаю простую логику функционирования КА. Что бы не терять эти 3 такта и выставляю адреса с учетом этой задержки (что бы была конвеерная схема). Но это приводит к усложнению конечного автомата и по сути сводит на нет преимущества "контроллера" памяти как такового и не позволяет построить "гибкий" конечный автомат(его функционирование жестко привязанно к конкретному контроллеру памяти). Вариантов решения проблемы я вижу 3: 1. Вообще отказаться от "контроллера" памяти как такового 2. Сделать "микропрограмный" контроллер памяти, в котором "зашиты" требуемые переходы по адресам.(благо они у меня фиксированные) 3. Сделать "конвееризируемый" контроллер памяти с очередью команд и т.д. А может быть эта задача решаеться проще ? ЗЫ. Сильно не пинайте, я только учюсь.
  19. Цитата(CaPpuCcino @ Jun 21 2005, 17:23)ну так и в чём проблема? выставляй действительно адрес за 3 такта, если он тебе конечно тогда уже известен. (это к стати не называется конвейером) по поводу усложнения - ну- нужно чем-то жертвовать (как альтернатива - можно считать на калькуляторе или счётах). мне не совсем ясна задача - построить арифм блок - или написать контроллер памяти? а какая память? судя по описанию SRAM рпитом NoBL/ZBT (zero bus turn-around) - IMHO придётся усложнять арифм блок Проблема в том, что я хочу разбить проект на независимые блоки, у меня есть 5 арфим. блоков (с разной математикой, но одинаковым скелетом) и каждый работает со своим блоком двухпортовой памяти, но расчет адреса считывания у них требует от 1 до 4 тактов(определяеться глубиной логики, можно сделать все за 1 такт, но тогда я не укладываюсь в тактовую частоту ). Вот я и хочу сделать универсальное решение, что бы потом, если измениться требование по тактовой частоте изменить только часть контроллеров памяти, которая отвечает за расчет адреса и изменить его латентность. А не изменять арифм.блоки, что потребует большего времени для проверки. Т.е. арифм. блок загрузил контроллер работой и ждет от него стробов, формируя запросы на чтение (добавление очереди адресов) не "точно вовремя" а когда ему удобно и при этом не терять время на ожидание. Спасибо всем! Сам разобрался, (пошел не по тому пути интеграции проекта ).
  20. Цитата(k2i @ Jun 20 2005, 03:42)на VHDL ПЗУ: type rom_type is array(255 downto 0) of integer range 0 to 255; constant rom: rom_type := (1, 2, 3, ....., 100); Как на Verilog просто описать ПЗУ? компоненту поставить и через defparam
  21. Цитата(dxp @ Jun 17 2005, 08:38)Почему нет? Так и делаю. Просто синхронный сброс - он обычно по какой-то логике возникает (ну, там счетчик обнулить или регистр), тут асинхронка может траблы создать. А при начальной инициализации - чтобы привести всю схему в исходное состояние, асинхронка, имхо, вполне себе вариант. Понял спасибо.
  22. Цитата(Serega Doc @ Jun 17 2005, 07:53)Кто нибудь может мне объяснить почему когда я переделываю асинхронный сброс на синхронный то увеличивается тактовая частота? Хмм а как вы оцениваете частоту ? И вопрос гуру: допустимо ли использование обоих видов сброса? асинхронный для первоначальной синхронизации и синхронный при работе?
  23. Цитата(DLR @ Jun 16 2005, 04:59)Делаю проект, по маленьким кусочкам работал, собрал целиком - такое г... Почти ни чего не трассируется, может кто помочь, подсказать что в проекте не так работает? P.S. Проект написан в ISE 6.3 на VHDL, с использованием CoreGen FIFO и примитивов xilinx. Можно гавно - расшифровать подробнее ?? что не работает и т.д.
  24. Столкнулся со следующей проблемой: есть проект для ISE, в модулях прописаны атрибуты для сигналов в, назовем его так, Ксайлиновском стиле. Решил загнать все это дело в симплифай 8.1 и естественно что он синтезирует не так, как было задумано, потому что у него прнято другое соглашение об атрибутах синтеза. В проекте для ИСЕ все используемый атрибуты прописанны в одном пакете, можно ли как нибудь подменить имена атрибутов ? т.е. например что бы ксайлиновский USE_DSP48 симплифай считал как свой syn_dspstyle? Не очень то хочеться в ручную все перелопачивать
  25. Цитата(sazh @ Jun 15 2005, 14:15)"класс  осталось только AHDL в VHDL/Verilog перевести " //-- Покладов Александр         //-- Делитель частоты         //-- Выходная частота равна Fout = Fin * (cDiv / (2 ^ cRg))         //-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!         //-- ! Fout не может быть больше Fin, т.е. cDiv < (2 ^ cRg)         //-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!         //Constant cDiv = 6; -- коэффициент деления         //Constant cRg = 3; -- количество разрядов в регистре фазы         module fr_div         (           input  Fin,           output Fout         );         parameter cDiv = 3'd6; parameter cRg = 3; reg [cRg:0] fv;  //-- Регистр сумматора reg          rgF_tff; wire        Fin_X_2; assign Fout = fv[cRg]; // -- Выход частоты assign Fin_X_2 = Fin ^ rgF_tff; // -- Умножение на 2 Fin always @(posedge Fin_X_2) // -- Удвоенная частота begin rgF_tff <= rgF_tff ^ 1'b1; fv <= fv + cDiv; // -- Сумматор фазы end endmodule уже и пошутить нельзя