реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Память на плис, реализация памяти на VHDL или Coregen
iosifk
сообщение Sep 17 2015, 09:29
Сообщение #16


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(Anton1990 @ Sep 17 2015, 12:21) *
Ну с коркой фифо я уже говорил работает лучше. Хочу узнать свои проблемы. Сигнал Rd это клок - по преднему фронту данные выставляются на шину PCI. Как таковой клок шины я не использую.

Тогда и говорить не о чем... Если данные не согласованы с клоком шины PCI, то результат как раз таким и будет...
И еще раз. Я Вам объясняю, что у Ксаййлинкса есть библиотечные компоненты, которые и надо использовать в таких случаях. Без всяких корегенов... А из c:\Xilinx\14.7\ISE_DS\ISE\verilog\src\unisims\..


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Anton1990
сообщение Sep 17 2015, 12:45
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 155
Регистрация: 26-04-12
Пользователь №: 71 584



Цитата(iosifk @ Sep 17 2015, 12:29) *
Тогда и говорить не о чем... Если данные не согласованы с клоком шины PCI, то результат как раз таким и будет...
И еще раз. Я Вам объясняю, что у Ксаййлинкса есть библиотечные компоненты, которые и надо использовать в таких случаях. Без всяких корегенов... А из c:\Xilinx\14.7\ISE_DS\ISE\verilog\src\unisims\..


Сигнал Rd от шины совершенно непричем. Ведь я его использую и с корегеновской коркой. Да и к томуже если я делаю память не на 65536 отсчетов на например 1024 то проблем никаких не возникает. Как я понимаю проблема имеено в размешении блоков памяти по кристалу при большом используемом количестве. Ну может я, конечно, и ошибась где-то. Но на основе своего опыта (довольно большого) могу сказать что элементы сгенерированные корегеном работаю стабильнее будьто память, простые умножители или фильтры построенные на умножителях. Разумного объяснения у меня этому нет.

Цитата(Maverick @ Sep 17 2015, 12:25) *
пример

[code]-- Following is the equivalent VHDL code for a 4-bit register with a positive-edge clock, asynchronous set and clock enable.
library ieee;
use ieee.std_logic_1164.all;


Вы намекаете что в одном условии нельзя записывать условие клока и разрешения
if clk'event and clk='1' and ce='1' then ...
а нужно так
if ce='1' then
if clk'event and clk='1' then ...
или о чем речь?
Go to the top of the page
 
+Quote Post
iosifk
сообщение Sep 17 2015, 13:06
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(Anton1990 @ Sep 17 2015, 15:45) *
Сигнал Rd от шины совершенно непричем. Ведь я его использую и с корегеновской коркой. Да и к томуже если я делаю память не на 65536 отсчетов на например 1024 то проблем никаких не возникает. Как я понимаю проблема имеено в размешении блоков памяти по кристалу при большом используемом количестве. Ну может я, конечно, и ошибась где-то. Но на основе своего опыта (довольно большого) могу сказать что элементы сгенерированные корегеном работаю стабильнее будьто память, простые умножители или фильтры построенные на умножителях. Разумного объяснения у меня этому нет.

У Вас в виртекс 6 есть блоки 32K × 1... Так вот, возьмите две группы по 16 блоков. И каждый блок - подключите к одному биту данных... По входу данные от АЦП подать параллельно на обе группы, а выбор группы определять по сигналу разрешение записи. А его взять от старшего разряда счетчика.
Теперь по выходу FIFO... Поскольку по чтению вообще спешить некуда, то можно блоки прицепить к 32 битам а при чтении учитывать старшее или младшее слово...
Или так...
учитывая, что чтение идет медленно, то модно сделать и мультиплексор по выходу... Или же брать FIFO с разрядностью 1 на входе и 2 на выходе...
При таком раскладе точно не будет мультиплексоров по данным на входе, а значит, что легче будет развести проект по кристаллу.
И скорее всего визард так и делает. А компилятор - нет. Посмотрите, что получается после компиляции - оптимизации...
Вот потому я всегда такие вещи делаю сам...
А если совсем честно, то тут не нужно FIFO, а нужна обычная память с шинами на запись и на чтение... И с одним клоком на 200 Мгц... весь проект сделать на этой частоте.
А клок от PCI можно привести к клоку 200 Мгц.


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Maverick
сообщение Sep 17 2015, 13:06
Сообщение #19


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(Anton1990 @ Sep 17 2015, 15:45) *
Вы намекаете что в одном условии нельзя записывать условие клока и разрешения
if clk'event and clk='1' and ce='1' then ...
а нужно так
if ce='1' then
if clk'event and clk='1' then ...
или о чем речь?

я намекаю на
Код
if (C'event and C='1')then  
          if (CE='1') then


+

Код
if rd'event and rd='1' then
Ard <= Ard + 2; --адреса преребираем через два т.к. шина PCI 32 разряда
end if;

для синтезатора это счетчик работающий на тактовой частоте rd

мне не понятно, например, почему сигнал q_thres окончания наполнения данными в память, не передается на схему вычитки в PCI через синхронизирующие регистры?
Как я понял по q_thres начинается вычитка данных из памяти.
Мне не понятен обмен готовности выполнения различных процессов и/или синхронизации работы схем:
- запись данных в блочную память с АЦП
- вычитка данных из блочной памяти для PCI

PS Ваше описание мне тяжело читать. Разнесите в разные процессы
- запись данных в блочную память с АЦП
- вычитка данных из блочной памяти для PCI


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
Anton1990
сообщение Sep 17 2015, 13:12
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 155
Регистрация: 26-04-12
Пользователь №: 71 584



Цитата(Maverick @ Sep 17 2015, 16:06) *
я намекаю на
Код
if (C'event and C='1')then  
          if (CE='1') then

А есть разница ?
Go to the top of the page
 
+Quote Post
Maverick
сообщение Sep 17 2015, 13:22
Сообщение #21


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(Anton1990 @ Sep 17 2015, 16:12) *
А есть разница ?

есть


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 17 2015, 13:25
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



есть, потому что синтезаторы анализирует текст на поиск известных им конструкций, с обще принятым описанием. Записав их по другому вы просто мешаете синтезатору понимать что вы хотели. Тут не как в С, тут не компилируется каждый оператор, тут все сложнее...
Go to the top of the page
 
+Quote Post
Anton1990
сообщение Sep 17 2015, 13:48
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 155
Регистрация: 26-04-12
Пользователь №: 71 584



Цитата(Maverick @ Sep 17 2015, 16:06) *
я намекаю на
Код
if (C'event and C='1')then  
          if (CE='1') then


+

Код
if rd'event and rd='1' then
Ard <= Ard + 2; --адреса преребираем через два т.к. шина PCI 32 разряда
end if;

для синтезатора это счетчик работающий на тактовой частоте rd

мне не понятно почему сигнал q_thres окончания наполнения данными в память, не передается на схему вычитки в PCI через синхронизирующие регистры?
Как я понял по q_thres начинается вычитка данных из памяти.
Мне не понятен обмен готовности выполнения различных процессов - синхронизации работы:
- запись данных в блочную память с АЦП
- вычитка данных из блочной памяти для PCI

PS Ваше описание мне тяжело читать


Все верно счетчик адресов счения радотает по Rd. q_thres записывается в full он и передается в шину для считывания программой.
Разумеется читать чужой код с неполными данными об отсутствии окружения данного блока и кода программы верзнего уровня сложно. Тут мне указывают на неправильность конструкций if then.. Если это действительно неправильно то нужно исправить и посмотреть на результат. Я, конечно, давно знаю что VHDL довольно геморойная вешь как бы лесно его не описывали, но это для меня открытие.

Цитата(Golikov A. @ Sep 17 2015, 16:25) *
есть, потому что синтезаторы анализирует текст на поиск известных им конструкций, с обще принятым описанием. Записав их по другому вы просто мешаете синтезатору понимать что вы хотели. Тут не как в С, тут не компилируется каждый оператор, тут все сложнее...


Ну то что здесь все сложнее я знаю, но нужно попробовать исправить и посмотреть. А так вообще спасибо. Если Вы правы то мне много придется исправлять.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 17 2015, 13:59
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



строго говоря я думаю что именно в этом случае синтезатор разберется и так и сяк, они все умнее и умнее становятся. Но на всякий случай проверить стоит.

И по сути проблемы, какой клок на PCI по которому уходят данные?
Go to the top of the page
 
+Quote Post
Anton1990
сообщение Sep 17 2015, 14:41
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 155
Регистрация: 26-04-12
Пользователь №: 71 584



Цитата(Golikov A. @ Sep 17 2015, 16:59) *
строго говоря я думаю что именно в этом случае синтезатор разберется и так и сяк, они все умнее и умнее становятся. Но на всякий случай проверить стоит.

И по сути проблемы, какой клок на PCI по которому уходят данные?


А что значит какой клок на PCI? Это сигнал чтения который поступает в мою ПЛИС от контроллера PCI. По этому сигналу я выбираю данные из памяти на выходную шину и им же открываю выходной bufe. А уже на самой шине PCI данные защелкиваются натуральным клоком от PCI (но это меня уже не касается). У меня в проекте целая куча регистров читается таким образом. Вообще схема отработанная годами. Память в плис с точки зрения логики ее чтения ничем не отличается от большой кучи регистров. А следовательно проблема в правильной записи в эти ''регистры''.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 17 2015, 18:36
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Вообще схема отработанная годами. Память в плис с точки зрения логики ее чтения ничем не отличается от большой кучи регистров. А следовательно проблема в правильной записи в эти ''регистры''.

то есть у вас все работает и проблем никаких нет, да?

наводящий вопрос
Как вы думаете регистр состоящий из Д триггеров, который может быть размещен в любом месте плис и ячейка памяти расположенная в блоке, с адресацией, имеют одинаковое время распространения сигнала от них до точки где данные захлопнуться?
Как вы думаете может такое получиться что вы выставите желаемый адрес по которому хотите считать данные так близко к моменту защелкивания данных, что не все сигналы успели дойти до регистра защелкивающего данные в другой части ПЛИС, к фронту клока управляющего этим регистром?
Go to the top of the page
 
+Quote Post
iosifk
сообщение Sep 17 2015, 19:16
Сообщение #27


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(Golikov A. @ Sep 17 2015, 21:36) *
то есть у вас все работает и проблем никаких нет, да?

наводящий вопрос
Как вы думаете регистр состоящий из Д триггеров, который может быть размещен в любом месте плис и ячейка памяти расположенная в блоке, с адресацией, имеют одинаковое время распространения сигнала от них до точки где данные захлопнуться?
Как вы думаете может такое получиться что вы выставите желаемый адрес по которому хотите считать данные так близко к моменту защелкивания данных, что не все сигналы успели дойти до регистра защелкивающего данные в другой части ПЛИС, к фронту клока управляющего этим регистром?


Вот две строки:

if rd'event and rd='1' then
bufDO(15 downto 0) <= Mem(conv_integer(Ard)); --вынимаем из памяти два отсчета данных
bufDO(31 downto 16) <= Mem(conv_integer(Ard+1));

Скажите, как происходит
Mem(conv_integer(Ard)); --вынимаем из памяти два отсчета данных

и Ard+1

Что там с латентностью? И насколько быстро произойдет "Ard+1" и потом Mem(conv_integer(Ard+1));
И все это за один фронт "rd'event and rd='1'" при том, что больше клоков то нет.... Только один этот фронт...
Т.е. это скорее всего счетчик, который идет на младшее слово. А с него же адрес идет на сумматор, и после сумматора на старшее??? Или это действительно две ячейки памяти и по выходу мультиплексор?

И если сравнивать с регистрами, то память медленнне раза в два....


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Anton1990
сообщение Sep 18 2015, 06:08
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 155
Регистрация: 26-04-12
Пользователь №: 71 584



Цитата(Golikov A. @ Sep 17 2015, 21:36) *
то есть у вас все работает и проблем никаких нет, да?

наводящий вопрос
Как вы думаете регистр состоящий из Д триггеров, который может быть размещен в любом месте плис и ячейка памяти расположенная в блоке, с адресацией, имеют одинаковое время распространения сигнала от них до точки где данные захлопнуться?
Как вы думаете может такое получиться что вы выставите желаемый адрес по которому хотите считать данные так близко к моменту защелкивания данных, что не все сигналы успели дойти до регистра защелкивающего данные в другой части ПЛИС, к фронту клока управляющего этим регистром?


По первой части ответ очевиден - время распространения разное.
По второй части вопрос не доконца понял. Но отвечу так. Если частота выставления адреса чтения очень низкая, то проблем быть не должно. Наверное.

Цитата(iosifk @ Sep 17 2015, 22:16) *
Вот две строки:

if rd'event and rd='1' then
bufDO(15 downto 0) <= Mem(conv_integer(Ard)); --вынимаем из памяти два отсчета данных
bufDO(31 downto 16) <= Mem(conv_integer(Ard+1));

Скажите, как происходит
Mem(conv_integer(Ard)); --вынимаем из памяти два отсчета данных

и Ard+1

Что там с латентностью? И насколько быстро произойдет "Ard+1" и потом Mem(conv_integer(Ard+1));
И все это за один фронт "rd'event and rd='1'" при том, что больше клоков то нет.... Только один этот фронт...
Т.е. это скорее всего счетчик, который идет на младшее слово. А с него же адрес идет на сумматор, и после сумматора на старшее??? Или это действительно две ячейки памяти и по выходу мультиплексор?

И если сравнивать с регистрами, то память медленнне раза в два....


Mem(conv_integer(Ard)); --вынимаем из памяти два отсчета данных
комментарий сразу к двум строкам относиться.

Что касается Ard+1, то у меня были по этому поводу сомнения. Взял да убрал чтения сразу двух отсчетов, теперь пишем в память 16 разрядов и читает из памяти 16 разрядов. Ну стало считываться в ПК в 2 раза медленнее ну и пофиг. НО общая проблема осталась.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 18 2015, 06:25
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Если частота выставления адреса чтения очень низкая, то проблем быть не должно. Наверное.


Возможно у вас клоком памяти как раз становиться rd сигнал, клоком второго порта, надо поглядеть разводку.

тогда у вас цепочка действий

- по сигналу rd защелкиваем в выходной регистр памяти данные по заданному адресу
- по какому-то внутреннему вам не известному клоку данные с памяти защелкнули на отправку.

эту цепочку можно повторять часто, редко, можно 1 раз и поймать ошибку, важно сколько времени проходит между rd и внутренним клоком, может так оказаться что данные просто не успевают выбраться из памяти и дойти до момента их захвата. Из регистров это все значительно быстрее, а в ФИФО данные к моменту забора на выходе уже готовы.
Go to the top of the page
 
+Quote Post
Maverick
сообщение Sep 18 2015, 06:56
Сообщение #30


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(Anton1990 @ Sep 18 2015, 09:08) *

Общее, что у Вас должно быть:
- память двух портовая с двумя клоками (своя тактовая частота для каждого порта памяти):
CODE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity memA0 is
generic
(
DATA_WIDTH : natural := 4;
ADDR_WIDTH : natural := 13
);

port
(
clk_a : in std_logic;
clk_b : in std_logic;
addr_a : in std_logic_vector((ADDR_WIDTH-1) downto 0);
addr_b : in std_logic_vector((ADDR_WIDTH-1) downto 0);
data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);
data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);
we_a : in std_logic := '1';
we_b : in std_logic := '1';
q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);
q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)
);

end memA0;

architecture Behavioral of memA0 is

-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;

shared variable ram : memory_t:= (others => (others => '0'));
-- signal ram : memory_t :=
--(
-- to initialize memory
-- );
signal mem_data : std_logic_vector (14 downto 0);


begin

-- Port A
process(clk_a)
begin
if(rising_edge(clk_a)) then
if(we_a = '1') then
ram(conv_integer(addr_a)) := data_a;
end if;
q_a <= ram(conv_integer(addr_a));
end if;
end process;

-- Port B
process(clk_b)
begin
if(rising_edge(clk_b)) then
if(we_b = '1') then
ram(conv_integer(addr_b)) := data_b;
end if;
q_b <= ram(conv_integer(addr_b));
end if;
end process;

end Behavioral;


- схема записи данных с АЦП должна соединяться с одним портом памяти на своей тактовой частоте (у Вас вроде это clk).
- схема вычитки данных для PCI должна соединяться с другим портом памяти на своей тактовой частоте (у Вас вроде это rd).
- сигналы квитирования или готовности данных должны быть пропущены через синхронизирующую цепочку регистров. Это необходимо когда Вы производите передачу готовности с одной схемы в другую.

PS Можно вместо предложенной памяти использовать ФИФО (тоже на 2 клока для входа и выхода).


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:30
Рейтинг@Mail.ru


Страница сгенерированна за 0.035 секунд с 7
ELECTRONIX ©2004-2016