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

 
 
14 страниц V  « < 11 12 13 14 >  
Reply to this topicStart new topic
> "Схемотехнические трюки для ПЛИСоводов", создание аналога "Алгоритмические трюки для программистов"
Flip-fl0p
сообщение Nov 13 2017, 08:18
Сообщение #181


В поисках себя...
***

Группа: Свой
Сообщений: 481
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(one_eight_seven @ Nov 13 2017, 11:09) *
Сравнение с нулём - это простое ИЛИ всех битов счётчика.

Сравнение с каким-то числом - это сначала XOR с заданным значением, после чего уже ИЛИ всех битов результата.

Но в ПЛИС то это реализуется на LUT (Look-Up Table) и на них без разницы как сравнивать, нули или конкретное значение.
Просто сказанное ниже, я имел ввиду применительно к ПЛИС:
Цитата
А какая разница ? Компаратору без разницы, что сравнивать, схема у него одинаковая, что для сравнения нулей или других чисел.


Сообщение отредактировал Flip-fl0p - Nov 13 2017, 08:22
Go to the top of the page
 
+Quote Post
nice_vladi
сообщение Nov 13 2017, 08:31
Сообщение #182


Участник
*

Группа: Участник
Сообщений: 36
Регистрация: 7-09-16
Из: Томск
Пользователь №: 93 239



Цитата(Flip-fl0p @ Nov 13 2017, 07:34) *
А какая разница ? Компаратору без разницы, что сравнивать, схема у него одинаковая, что для сравнения нулей или других чисел.

Другой вопрос, если нам надо например одним счетчиком отсчитывать разные интервалы. Например:
Счетчик досчитал до 10 - что-то делаем, и сбрасываем счетчик.
Счетчик досчитал до 15 - что-то делаем, и сбрасываем счетчик.
Счетчик досчитал до 18 - что-то делаем, и сбрасываем счетчик.
Счетчик досчитал до 24 - что-то делаем, и сбрасываем счетчик.
Счетчик досчитал до 32 - что-то делаем, и сбрасываем счетчик.
В этом случае у нас будет несколько схем сравнения с 10, 15, 18, 24, 32 - что собственно совсем не хорошо.
В случае если счетчик считает до 0 у нас будет только 1 схема сравнения с нулем.


А установка регистра счетчика в какую-то начальную величину не будет занимать логику? Т.е., получается, при счете до нуля мы тратим логику на инициализацию счетчика, а при счете до константы тратим логику на сравнение значения счетчика с константой, я правильно понимаю?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 13 2017, 08:31
Сообщение #183


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 7 934
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Если сравнивать с нулем и только с нулем, а при загрузке задавать произвольное значение счетчика, будет проще и быстрее, чем сравнивать с произвольным значением и сбрасывать счетчик.
Go to the top of the page
 
+Quote Post
one_eight_seven
сообщение Nov 13 2017, 08:33
Сообщение #184


Знающий
****

Группа: Участник
Сообщений: 749
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664



Цитата
Но в ПЛИС то это реализуется на LUT (Look-Up Table) и на них без разницы как сравнивать, нули или конкретное значение.
Просто сказанное ниже, я имел ввиду применительно к ПЛИС:

Даже если LUT, то в случае ИЛИ - одна ячейка обрабатывает столько бит входных данных, сколько у неё входов, в случае же сравнения с загруженным числом, на каждый бит нужен регистр. Да и интерконнект сильнее нагружается. Хотя, тут настаивать не буду - с ПЛИСами работаю крайне мало.
Go to the top of the page
 
+Quote Post
nice_vladi
сообщение Nov 13 2017, 09:02
Сообщение #185


Участник
*

Группа: Участник
Сообщений: 36
Регистрация: 7-09-16
Из: Томск
Пользователь №: 93 239



Цитата(ViKo @ Nov 13 2017, 08:31) *
Если сравнивать с нулем и только с нулем, а при загрузке задавать произвольное значение счетчика, будет проще и быстрее, чем сравнивать с произвольным значением и сбрасывать счетчик.


Почему так? Как было сказано выше, компаратору нет разницы, какие данные у него на входе. Нули-не нули, он все равно будет их сравнивать, так же, как и полноценные данные.

Ну и с точки зрения наглядности - гораздо понятнее событие, которое происходит через Н тактов (запись cnt == N), чем событие, которое происходит, когда счетчик в 0( cnt == 0, а инициализация где-то в другой части модуля, например). Хотя тут уже вопрос привычки, я думаю.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 13 2017, 09:07
Сообщение #186


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 7 934
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(nice_vladi @ Nov 13 2017, 12:02) *
Почему так? Как было сказано выше, компаратору нет разницы, какие данные у него на входе. Нули-не нули, он все равно будет их сравнивать, так же, как и полноценные данные.

Как было сказано выше :-), сравнить только с нулем - это объединить биты по ИЛИ.
Кроме того, я вообще не сравниваю биты счетчика, а использую бит переноса. Которым загружаю в счетчик число, хранящееся в рядом находящемся регистре.
Go to the top of the page
 
+Quote Post
alxkon
сообщение Nov 13 2017, 09:51
Сообщение #187


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

Группа: Участник
Сообщений: 79
Регистрация: 16-11-10
Пользователь №: 60 920



Цитата(ViKo @ Nov 13 2017, 13:07) *
Как было сказано выше :-), сравнить только с нулем - это объединить биты по ИЛИ.
Кроме того, я вообще не сравниваю биты счетчика, а использую бит переноса. Которым загружаю в счетчик число, хранящееся в рядом находящемся регистре.

А можете проилюстрировать в коде?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 13 2017, 10:27
Сообщение #188


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 7 934
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Вот. Последние варианты (4 и 5, одинаковые). Остальные показывают процесс разработки. :-)

CODE

`define LENTH 28
`define VAR5

`ifdef VAR1
`define TIM1
`elsif VAR2
`define TIM1
`elsif VAR3
`define TIM1
`else
`define TIM2
`endif

module Timer_m
`ifdef TIM1
(
(* chip_pin = "91",
altera_attribute = "-name global_signal on; -name io_standard lvds" *)
input bit clk, // high-speed clock
input bit [`LENTH-1:0] rld, // reload data
output bit pls // timer overload pulse
);
`endif

`ifdef VAR1
bit [`LENTH:0] cnt;
always_ff @(posedge clk) begin
if (cnt[`LENTH]) cnt <= {1'b0, rld};
else cnt <= cnt - 1;
end
assign pls = cnt[`LENTH];

`elsif VAR2
bit [`LENTH-1:0] cnt;
always_ff @(posedge clk) begin
if (cnt[`LENTH-1]) cnt <= rld;
else cnt <= cnt - 1;
end
assign pls = cnt[`LENTH-1];

`elsif VAR3
bit [`LENTH-1:0] cnt;
always_ff @(posedge clk) begin
if (cnt[`LENTH-1]) cnt <= rld;
else cnt <= cnt[`LENTH-2:0] - 1;
end
assign pls = cnt[`LENTH-1];
`endif

`ifdef TIM2
(
(* chip_pin = "91",
altera_attribute = "-name global_signal on; -name io_standard lvds" *)
input bit clk, // high-speed clock
input bit [`LENTH-1:0] rld, // reload data
input bit ldp, // load pulse
output bit pls // timer overload pulse
);
`endif

`ifdef VAR4
bit [`LENTH:0] cnt;
always_ff @(posedge clk) begin
if (cnt[`LENTH]) cnt <= {ldp, rld};
else cnt <= cnt[`LENTH-1:0] - 1;
end
assign pls = cnt[`LENTH];
`endif

`ifdef VAR5
bit [`LENTH-1:0] cnt;
always_ff @(posedge clk) begin
if (pls) {pls, cnt} <= {ldp, rld};
else {pls, cnt} <= cnt - 1;
end
`endif

endmodule : Timer_m
Go to the top of the page
 
+Quote Post
Timmy
сообщение Nov 13 2017, 10:36
Сообщение #189


Знающий
****

Группа: Участник
Сообщений: 822
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Если речь о счётчике, то выгодней вообще не сравнивать все биты, а прекращать счёт при смене знака, то есть при переходе 0 -> -1 или -1 -> 0 в зависимости от направления счёта.
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Dec 29 2017, 19:44
Сообщение #190


В поисках себя...
***

Группа: Свой
Сообщений: 481
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Может кому пригодится. Обычный счетчик с синхронным сбросом и сигналом разрешения работы.
Основной "фишкой" счетчика является возможность выбора направление счета, и уменьшение занимаемого места если коэффициент пересчета это 2^n.

CODE
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY KAA_COUNTER_ENA_SCLR IS
GENERIC
(
DIRECTION : STRING := "UP"; -- UP / DOWN Направление счета
MAX_VALUE : INTEGER := 127 -- До скольки считает счетчик(от нуля до MAX_VALUE)
);
PORT
(
CLK : IN STD_LOGIC;
ENA : IN STD_LOGIC;
SCLR : IN STD_LOGIC;
DATA_OUT : OUT INTEGER RANGE 0 TO MAX_VALUE
);
END ENTITY;

ARCHITECTURE RTL OF KAA_COUNTER_ENA_SCLR IS
--=====================================================================
-- Функция определения разрядности шины - логарифм по основанию 2
--=====================================================================
FUNCTION LOG2 (MAX_VALUE : INTEGER) RETURN INTEGER IS -- Функция вычесления логарифма по основанию 2 для определения разрядности
VARIABLE CNT : INTEGER := 0; -- Счетчик для подсчета количества делений на 2
VARIABLE TEMP : INTEGER := MAX_VALUE + 1; -- Делимое - это максимальное количество СОСТОЯНИЙ счетчика
BEGIN
WHILE (TEMP > 1) LOOP -- Пока делимое больше 1 совершаем цикл деления на 2
CNT := CNT + 1 ; -- Считаем количество циклов деления
TEMP := TEMP/2; -- Делим число на 2 каждый цикл
END LOOP;
RETURN CNT; -- Значение счетчика и есть логарифм
END LOG2;

SIGNAL COUNTER_INTEGER : INTEGER RANGE 0 TO MAX_VALUE := 0; -- Счетчик обнуляемый условием максимального счета
SIGNAL COUNTER_UNSIGNED : UNSIGNED(LOG2(MAX_VALUE)-1 DOWNTO 0) := (others => '0'); -- Счетчик с автомватическим обнулением при переполнении
BEGIN

--================================================================================
==========================
-- Если максимальное значение счетчика переведенное в двоичное число не состоит из одних только единиц
-- Значит у нас счетчик обнуляется значением максимального счета т.е до наступления переполнения разрядов
--================================================================================
==========================
COUNTER_INTEGER_GEN : IF ( TO_UNSIGNED(MAX_VALUE,LOG2(MAX_VALUE) ) /= ( LOG2(MAX_VALUE)-1 DOWNTO 0 => '1' ) ) GENERATE
CNT_PROC : PROCESS
(
CLK
)
BEGIN
IF (RISING_EDGE(CLK)) THEN
--==========================================================================
-- Генерируем суммирующий счетчик обнуляющийся максимальным значением счета
--==========================================================================
IF (DIRECTION = "UP") THEN -- Если направление счета "вверх" генерируется суммирующий счетчик
IF (ENA = '1') THEN -- При активном сигнале разрешения раблоты
IF (COUNTER_INTEGER = MAX_VALUE) THEN -- При наступлении максимального значения счетчика
COUNTER_INTEGER <= 0; -- Обнулим его
ELSE
COUNTER_INTEGER <= COUNTER_INTEGER + 1; -- Иначе будем его инкрементировать
END IF;
END IF;
IF (SCLR = '1') THEN -- При активном синхронном сбросе
COUNTER_INTEGER <= 0; -- Сбросим счетчик в ноль
END IF;
END IF;
--==========================================================================
-- Генерируем вычитающий счетчик обнуляющийся максимальным значением счета
--==========================================================================
IF (DIRECTION = "DOWN") THEN -- Если направление счета "вниз" то генерируется вычитающий счетчик
IF (ENA = '1') THEN -- При активном сигнале разрешения раблоты
IF (COUNTER_INTEGER = 0) THEN -- При наступлении максимального значения счетчика
COUNTER_INTEGER <= MAX_VALUE; -- Обнулим его
ELSE
COUNTER_INTEGER <= COUNTER_INTEGER - 1; -- Иначе будем его декрементировать
END IF;
END IF;
IF (SCLR = '1') THEN -- При активном синхронном сбросе
COUNTER_INTEGER <= MAX_VALUE; -- Сбросим счетчик в максимальное значение
END IF;
END IF;
END IF;
END PROCESS;
DATA_OUT <= COUNTER_INTEGER; -- Выдадим значение счетчика на выходные порты модуля
END GENERATE;

--================================================================================
==========================
-- Если максимальное значение счетчика это (2**N - 1)
-- Значит у нас полный счетчик, который обнуляется переполнением разрядов
--================================================================================
==========================
COUNTER_UNSIGNED_GEN : IF ( TO_UNSIGNED(MAX_VALUE,LOG2(MAX_VALUE) ) = ( LOG2(MAX_VALUE)-1 DOWNTO 0 => '1' ) ) GENERATE
CNT_PROC : PROCESS
(
CLK
)
BEGIN
IF (RISING_EDGE(CLK)) THEN
--==========================================================================
-- Генерируем суммирующий счетчик обнуляющийся переполнением разрядов
--==========================================================================
IF (DIRECTION = "UP") THEN -- Если направление счета "вверх" генерируется суммирующий счетчик
IF (ENA = '1') THEN -- При активном сигнале разрешения раблоты
COUNTER_UNSIGNED <= COUNTER_UNSIGNED + "1"; -- Инкрементируем его каждый такт
END IF;
IF (SCLR = '1') THEN -- При активном синхронном сбросе
COUNTER_UNSIGNED <= (OTHERS => '0'); -- Сбросим счетчик в ноль
END IF;
END IF;
--==========================================================================
-- Генерируем вычитающий счетчик обнуляющийся переполнением разрядов
--==========================================================================
IF (DIRECTION = "DOWN") THEN -- Если направление счета "вниз" то генерируется вычитающий счетчик
IF (ENA = '1') THEN -- При активном сигнале разрешения раблоты
COUNTER_UNSIGNED <= COUNTER_UNSIGNED - "1"; -- Декрементируем его каждый такт
END IF;
IF (SCLR = '1') THEN -- При активном синхронном сбросе
COUNTER_UNSIGNED <= TO_UNSIGNED(MAX_VALUE,LOG2(MAX_VALUE) ); -- Сбросим счетчик в единицы
END IF;
END IF;
END IF;
END PROCESS;
DATA_OUT <= TO_INTEGER(COUNTER_UNSIGNED); -- Выдадим значение счетчика на выходные порты модуля
END GENERATE;
END ARCHITECTURE;
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Dec 30 2017, 04:54
Сообщение #191


Профессионал
*****

Группа: Свой
Сообщений: 1 846
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Нет проверки на то, что что в DIRECTION будет нечто, отличное от "UP" и "DOWN". Например, "Up" или "Down". Не всем нравится верхний регистр. Лучше заменить строку на boolean.
От счётчика с integer никакого профита. То же самое можно сделать двоичным счётчиком. Тем более, что вы не сможете сделать integer-счётчик более 32 бит.
Есть старый программистский трюк: если число x является степенью 2, то
Код
x and (x - 1) = 0
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Dec 30 2017, 10:12
Сообщение #192


В поисках себя...
***

Группа: Свой
Сообщений: 481
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(andrew_b @ Dec 30 2017, 07:54) *
Нет проверки на то, что что в DIRECTION будет нечто, отличное от "UP" и "DOWN". Например, "Up" или "Down". Не всем нравится верхний регистр. Лучше заменить строку на boolean.
От счётчика с integer никакого профита. То же самое можно сделать двоичным счётчиком. Тем более, что вы не сможете сделать integer-счётчик более 32 бит.
Есть старый программистский трюк: если число x является степенью 2, то
Код
x and (x - 1) = 0

Спасибо за критику ! Я обязательно подумаю над этим.
Вот со счётчиками типа integer я не совсем согласен. Какой тип использовать в качестве выхода: SLV, integer, unsigned - зависит лишь от предпочтений разработчика. Никаких преимуществ SLV над integer нет, как и наоборот. Это лишь вопрос удобства. В конце концов, всегда значение можно преобразовать в тот тип, который нужен smile3046.gif

Сообщение отредактировал Flip-fl0p - Dec 30 2017, 10:12
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Dec 30 2017, 10:15
Сообщение #193


Профессионал
*****

Группа: Свой
Сообщений: 1 846
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(Flip-fl0p @ Dec 30 2017, 13:12) *
Никаких преимуществ SLV над integer нет, как и наоборот. Это лишь вопрос удобства. В конце концов, всегда значение можно преобразовать в тот тип, который нужен
Ну попробуйте сделать на integer счётчик разрядностью более 32 бит.
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Dec 30 2017, 10:31
Сообщение #194


В поисках себя...
***

Группа: Свой
Сообщений: 481
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(andrew_b @ Dec 30 2017, 13:15) *
Ну попробуйте сделать на integer счётчик разрядностью более 32 бит.

Вы снова правы ! biggrin.gif
Вот только мне ещё ни разу не приходилось работать с такими счетчиками...
Можете сказать навскидку где вообще такой счетчик мог бы пригодится ?
Go to the top of the page
 
+Quote Post
blackfin
сообщение Dec 30 2017, 10:50
Сообщение #195


Гуру
******

Группа: Свой
Сообщений: 2 767
Регистрация: 18-04-05
Пользователь №: 4 261



Цитата(Flip-fl0p @ Dec 30 2017, 13:31) *
Можете сказать навскидку где вообще такой счетчик мог бы пригодится ?

Для адресации внешней SDRAM памяти объемом 128 ГБайт. biggrin.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th January 2018 - 13:29
Рейтинг@Mail.ru


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