ASN 0 14 апреля, 2010 Опубликовано 14 апреля, 2010 · Жалоба Djony1987 1.Подход нормальный. Именно так и делают. Это знаковые решения с демодулятора. 2.В простейшем случае метрики вообще нормализировать не надо. Достаточно большой разрядности ACS. При необходимости можно просто "осадить" на несколько разрядов знаковым сдвигом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djony1987 0 15 апреля, 2010 Опубликовано 15 апреля, 2010 · Жалоба Djony1987 1.Подход нормальный. Именно так и делают. Это знаковые решения с демодулятора. 2.В простейшем случае метрики вообще нормализировать не надо. Достаточно большой разрядности ACS. При необходимости можно просто "осадить" на несколько разрядов знаковым сдвигом. Спасибо! 1. Это сделал. Т.к. максимум 14 (7+7), то на дистанцию 4 бита (16). На вход подается 2 значения по 3 бита. module Soft_dist_calc(InputBits, EncOut, OutputDistance); input [5:0] InputBits; input [1:0] EncOut; output [3:0] OutputDistance; reg [3:0] OutputDistance; always @(EncOut) begin case(EncOut) 2'b00: OutputDistance = InputBits[5:3] + InputBits[2:0]; 2'b01: OutputDistance = InputBits[5:3] + (7 - InputBits[2:0]); 2'b10: OutputDistance = (7 - InputBits[5:3]) + InputBits[2:0]; 2'b11: OutputDistance = (7 - InputBits[5:3]) + (7 - InputBits[2:0]); endcase end endmodule 2. У меня K=7, глубина 40 например, т.е. масимум может быть занчяения метрики пути в конце 40*14 = 520, лучше 10 бит взять на метрики? (можно глубину увеличить например в последующем) 3. Как лучше хранить метрики? В RAM или в регистровой памяти, как массив например reg [9:0] RAM [40(глубина)*64(состояний) - 1:0]; Спаисбо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ASN 0 15 апреля, 2010 Опубликовано 15 апреля, 2010 · Жалоба Djony1987 Как лучше виднее Вам (исходя из задачи). :) Обычно, для практической реализации, квантование до 6-ти битных входных значений достаточно. В цитируемой Вами книги, IMHO, есть обоснование. Поэтому, имеет смысл заложиться на 16 разрядов для метрики. Метрики и пути, IMHO, удобнее хранить в BRAM. Видимо, у Вас код (133,171). Для Вашего случая (для такой низкой скорости декодирования), как указал Grumbler_2002, всё уместится в одну BRAM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djony1987 0 15 апреля, 2010 Опубликовано 15 апреля, 2010 (изменено) · Жалоба Djony1987 Как лучше виднее Вам (исходя из задачи). :) Обычно, для практической реализации, квантование до 6-ти битных входных значений достаточно. В цитируемой Вами книги, IMHO, есть обоснование. Поэтому, имеет смысл заложиться на 16 разрядов для метрики. Метрики и пути, IMHO, удобнее хранить в BRAM. Видимо, у Вас код (133,171). Для Вашего случая (для такой низкой скорости декодирования), как указал Grumbler_2002, всё уместится в одну BRAM. 6-битные входные значения всмысле 2 по 3 бита, и тогда пройгрышь по сравнению с бесконечностью бит - 0.25 дБ. 16 не много? :) Насчет BRAM: 1) не очень понял взаимосвязь скорости декодирования и объемом памяти, как я понимаю объем необходимой памяти зависит от структуры декодера и размера метрик записываемых и т.д. 2) я в одном из постов дал ссылку на http://www.xilinx.com/itp/xilinx5/pdf/docs/xst/xst.pdf, пойдет ли для реализации декодера пример на стр. 165? Спасибо! Изменено 15 апреля, 2010 пользователем Djony1987 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ASN 0 15 апреля, 2010 Опубликовано 15 апреля, 2010 · Жалоба Djony1987 Под 6-битные входные значения понимаются знаковые входные числа в диапазоне -31 - +31. Соответственно у Вас -7 - +7. Но это не главное. Связь между скоростью декодирования и объёмом необходимой памяти прямая: количество тактов автомата, управляющего декодером. То есть при использовании только одной однопортовой памяти (как на стр. 165) эти действия будут происходить последовательно: прочитать первый операнд, прочитать второй операнд, выполнить ACS, сохранить первую метрику, сохранить вторую метрику, сохранить пути (после всех 64 рёбер). По сути машина состояний, которая управляет декодером, повторяем программную реализацию. Поэтому, IMHO, это и самый простой путь. Для увеличения скорости декодирования требуется распараллеливание вычислений. Как это делать - описано в книге, которую Вам подсказали. В Вашем случае (30 кБит/с) на частоте 30 МГц у Вас есть 1000 тактов на один бит. Грубая оценка: 1. Прямой проход : (чтение 1 операнда, чтение 2 операнда, ACS, запись 1 операнда, запись 2 операнда) * 32 + сохранение пути будут менее 200 тактов; 2. Обратный проход : Начальный поиск максимума - (чтение 1 операнда, сравнение на максимальную метрику, запись нового максимального значения) * 64 - менее 200 тактов (один раз для всех битов); Движение по путям декодирования - (чтение 1 операнда, сохранения решения) - 2 такта. Объём памяти оценить можно так: - память метрик - 16*64; - память путей - 64*на глубину декодирования; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djony1987 0 16 апреля, 2010 Опубликовано 16 апреля, 2010 (изменено) · Жалоба Djony1987 Под 6-битные входные значения понимаются знаковые входные числа в диапазоне -31 - +31. Соответственно у Вас -7 - +7. Но это не главное. Связь между скоростью декодирования и объёмом необходимой памяти прямая: количество тактов автомата, управляющего декодером. То есть при использовании только одной однопортовой памяти (как на стр. 165) эти действия будут происходить последовательно: прочитать первый операнд, прочитать второй операнд, выполнить ACS, сохранить первую метрику, сохранить вторую метрику, сохранить пути (после всех 64 рёбер). По сути машина состояний, которая управляет декодером, повторяем программную реализацию. Поэтому, IMHO, это и самый простой путь. Для увеличения скорости декодирования требуется распараллеливание вычислений. Как это делать - описано в книге, которую Вам подсказали. В Вашем случае (30 кБит/с) на частоте 30 МГц у Вас есть 1000 тактов на один бит. Грубая оценка: 1. Прямой проход : (чтение 1 операнда, чтение 2 операнда, ACS, запись 1 операнда, запись 2 операнда) * 32 + сохранение пути будут менее 200 тактов; 2. Обратный проход : Начальный поиск максимума - (чтение 1 операнда, сравнение на максимальную метрику, запись нового максимального значения) * 64 - менее 200 тактов (один раз для всех битов); Движение по путям декодирования - (чтение 1 операнда, сохранения решения) - 2 такта. Объём памяти оценить можно так: - память метрик - 16*64; - память путей - 64*на глубину декодирования; Спасибо за ответ! 16 бит как я понял надо брать, т.к. в BRAM можно записывать или по 8, или по 16 и т.д., т.е. кратно 2. (при этом 8 мало, остается 16). У меня 2 ACS - т.е. обрабатывается 1 бабочка. Т.е. уже надо 32 итерации на 1 пролет решетки. Если 2 ACS мне надо считывать из памяти 4 метрики пути, и после ACSов записывать две. Для хранения метрик = (16(бит на метрику)*64(состояния))*2 = 2048 бит - для хранения текущей и следующей метрик. Для хранения выживших нам надо - 64(состояния)*45(глубина) = 2889 бит - запоминается только LSB состояния. Тогда блок памяти для метрик: module RAM (clk, we, a, di, do); input clk; input we; input [6:0] a; input [15:0] di; output [15:0] do; reg [15:0] ram [127:0]; reg [6:0] read_a; always @(posedge clk) begin if (we) ram[a] <= di; read_a <= a; end assign do = ram[read_a]; endmodule А если использовать двухпортовую память скорость увеличится? Блок ACS: module ACS(CompareEnable, Distance0, Distance1, PathMetric0, PathMetric1, Metric, Survivor); input CompareEnable; input [3:0] Distance0, Distance1; input [15:0] PathMetric0, PathMetric1; output [15:0] Metric; output Survivor; wire [15:0] ADD0, ADD1; wire Survivir; wire [15:0] Temp_Metric, Metric; assign ADD0 = Distance0 + PathMetric0; assign ADD1 = Distance1 + PathMetric1; Comparator Comp(CompareEnable, ADD0, ADD1, Survivor); assign Temp_Metric = (Survivor) ? ADD1 : ADD0; assign Metric = (CompareEnable) ? Temp_Metric : ADD0; endmodule module Comparator(CompareEnable, Metric0, Metric1, Survivor); input CompareEnable; input [15:0] Metric0, Metric1; output Survivor; wire Surv; assign Surv = (Metric0 <= Metric1) ? 1'b0 : 1'b1; assign Survivor = (CompareEnable) ? Surv : 1'b0; endmodule Спасибо! Изменено 16 апреля, 2010 пользователем Djony1987 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 17 сентября, 2010 Опубликовано 17 сентября, 2010 (изменено) · Жалоба Добрый день Есть следующий вопрос по реализации декодера Витерби. Написал модель в матлабе, которая имитирует поведение той реализации, что будет на кристале Вопросы есть следующие 1) Функция трейбека реализована следующим образом for k=1:1:Trace_Back_Depth Curr_St=Nxt_State; Br=TB_Matrix(Truth_State,k); [Nxt_State,Out]=TraceBackUnit(Br,Curr_St); end Где function [Next_St,O_bit] = TraceBackUnit( Br,Curr_St ) REZ='000'; BIN=dec2bin(Curr_St-1,2); REZ(1:2)=BIN(1:2); REZ(3)=num2str(Br); Next_St=(bin2dec(REZ(2:3)))+1; O_bit=bin2dec(REZ(1)); end Состояния у меня нумеруются как 1-2-3-4, в бинарном виде 00-01-10-11, то есть от 0 до 3. В функции ТрейкБэкЮнит реализован следующий алгоритм К двоичному номеру состояния справа приписывается бит из матрицы трейк-бека. Тогда последнии биты номера состояния и добавленный бит образуют новое состояние, а оставшийся - выходной исходный бит. Например было состояние 3, в него мы попали по верхней линии (BR=0), номер этого состояния 10. Тогда 10_0=> следующее состояние 00, выход 1 Было состояние 01, пришли снизу BR=1, следующее состояние 11, выход 0 На VHDL я бы реализовал это на обычном сдвигом регистре, так как там нет проблем с заданием массива с 0 индексом, в матлабе все индексы начинаются с 1. Как реализовать эту процедуру по людски? Без постоянных переводов дек2бин и проч? Какие средства матлаб подходят для этих операций? 2) С памятью на ПЛИС до этого не работал, прочитал про разные виды, в голове пока еще каша. Нужно реализовать следующее - На вход памяти поступают вектор из 64 бит, далее начинается функция трейбека, которая доходит до конца памяти, выдавая биты вверх-вниз, после чего необходимо записать следующий вектор из 64. При этом последний вектор стирается. Одним словом требуется FIFO буфер, но с возможностью обращения к каждому элементу. Спасибо! Изменено 17 сентября, 2010 пользователем Muscat Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 17 сентября, 2010 Опубликовано 17 сентября, 2010 · Жалоба Добрый день Есть следующий вопрос по реализации декодера Витерби. Спасибо! Начинайте со структурно-функциональной схемы. Нарисуйте все цифровые модули и соединение между ними. Сперва какую-то обобщенную, потом более подробную. Опишите все функции, которые будет выполнять каждый модуль - тогда мысли упорядочатся. Тогда появятся конкретные вопросы по реализации... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 17 сентября, 2010 Опубликовано 17 сентября, 2010 · Жалоба Функциональную схему я нарисовал, модель в матлабе работает, еще я самостятельно кушаю и умею держать головку. Каши с алгоритмом у меня в голове нет, нет понимания как организовать память и как правильно проэмулировать в матлабе сдвиговый регистр. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x736C 0 17 сентября, 2010 Опубликовано 17 сентября, 2010 (изменено) · Жалоба ... как организовать память Как взятую из «визарда» одно- или двухпортовую память с необходимой для вашего функционала обвязкой в виде дополнительной регистрово-комбинационной логики ... как правильно проэмулировать в матлабе сдвиговый регистр Могу ошибаться в синтаксисе, но что-то вроде такого, может быть, подойдет: for i = 1:n-1 reg(i) = reg(i + 1) end Изменено 17 сентября, 2010 пользователем x736C Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 18 сентября, 2010 Опубликовано 18 сентября, 2010 (изменено) · Жалоба спасибо! Попробую еще раз объяснить, что я хочу. Обратившись к ячейке памяти 111 111 (взяв последний столбец из матрицы для трейбека), мы сразу попадали в начало памяти, как по кольцу, то есть в адрес 000 000,не тратя время на отматывание счетчика. Вот этот кольцевой счетчик реализуется отдельной схемой, или же есть вариант сразу организовать память, которая подойдет под эти требования? И еще хотелось бы какого нибудь материала про устройство и организацию памяти. ПП Схемотехнику Титце и Шенка смотрел. Хотелось бы более выосокоуровненвого. Coding Style Giude от Актеля и XST от ксайлинкса смотрел, хочется чего то более принципиального. По тому какие виды памяти бывают(применительно к встроенной в ПЛИС), как ее использовать, плюсы минусы подводные камни. По поводу матлаба вопрос не в логике "сдвига". К примеру заполнение матрицы трейбека сейчас работает так TB_Matrix(:,2:Trace_Back_Depth)=TB_Matrix(:,1:Trace_Back_Depth-1); TB_Matrix(:,1)=dec; Старый вектор TB_Matrix(:,Trace_Back_Depth) отбрасывается, остальные сдвигаются вправо, слева появляется новый вектор решений dec. Вопрос как раз с эмулированием двоичной логики. Идея трейкбека в том, что зная текущий адрес и имея бит вверх-вниз, мы сразу вычисляем куда мы должны отправиться по решетке. Сейчас это выглядит так 1) Выбрав минимальную метрику, смотрим номер состояния 2) Обращаемся в матрицу трейбека, снимаем бит вверх-вниз 3) Бинарник проталкиваем в регистр,добавляем бит вверх вниз 4) Снимаем номер нового состояния 5) Переводим его в десятичный, для обращения к матрице 6) Если трейбек не закончен обращаемся в пункт 2 Вот эти преобразования десятичный-двоичный и занимают много времени. Есть мысль при моделировании вообще отказаться от сдвига и все операции проводить над десятичными числами Изменено 18 сентября, 2010 пользователем Muscat Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 18 сентября, 2010 Опубликовано 18 сентября, 2010 · Жалоба С утра соображается явно быстрее. Если кому интересно, то трейбек реализовался вот так Код среды матлаб if j>=(Trace_Back_Depth) %Если буфер достаточно заполнен [Min_Metric,Truth_State]=min(State_Metric); %Поиск минимальной метрики Nxt_State=Truth_State; %За начальное состояние принимаем номер сост с мин.метрикой State_Metric=State_Metric-Min_Metric; %Такая вот примитивная нормализация for k=1:1:Trace_Back_Depth %Пошли вглубь решетки Br=TB_Matrix(Nxt_State,k); %Вверх или вниз? [Nxt_State,Out]=TraceBackUnit(Br,Nxt_State); %Определили куда попали end O_bit(j)=Out; %Окончательный выходной бит наружу end Та операция, которая вызывала вопросы, как реализовать бинарный регистр сдвига. Я решил вообще не влезать в бинарник, сделал вот так function [Next_St,O_bit] = TraceBackUnit( Br,Curr_St ) Register=(Curr_St-1)*2+Br; Next_St=rem(Register,4)+1; O_bit=idivide(int8(Register),int8(4)); %Главная задержка происходит именно в этом модуле % REZ='000'; % BIN=dec2bin(Curr_St-1,2); % REZ(1:2)=BIN(1:2); % REZ(3)=num2str(Br); % Next_St=(bin2dec(REZ(2:3)))+1; % O_bit=bin2dec(REZ(1)); end Закомментирована первоначальная версия кода, когда я пытался эмулировать регистр. Пока в таком варианте, с неглубоким трейбеком (5) и простым кодеком (3х(7 5)) 100k бит прогоняет за 16 секунд. Раньше на это требовалось около 2ух минут, ускорение почти в 10 раз. Буду дальше работать над оптимизацией. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 18 сентября, 2010 Опубликовано 18 сентября, 2010 · Жалоба Функциональную схему я нарисовал, модель в матлабе работает, еще я самостятельно кушаю и умею держать головку. Каши с алгоритмом у меня в голове нет, нет понимания как организовать память и как правильно проэмулировать в матлабе сдвиговый регистр. Вот читаю Ваши сообщения - не могу понять Вы не можете написать оптимизированную программу/модель в матлабе Декодера Витерби или Вам нужно реализовать этот Декодер Витерби в ПЛИС? Если вопросы связанные с матлабом,тогда лучше задать их здесь Если вопросы по ПЛИС - делитесь как Вы предполагаете перевести код матлаба в реализацию для ПЛИС (поэтому я и задал вначале такой вопрос). Оптимизация кусков кода матлаба хорошо, но объясните мне пожалуйста как влияет это на реализацию в ПЛИС? Вопросы по написанию программы/модели в матлабе и реализации в ПЛИС - совершенно разные вопросы. Пока в таком варианте, с неглубоким трейбеком (5) и простым кодеком (3х(7 5)) 100k бит прогоняет за 16 секунд. Раньше на это требовалось около 2ух минут, ускорение почти в 10 раз. Буду дальше работать над оптимизацией. На компьютере? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x736C 0 18 сентября, 2010 Опубликовано 18 сентября, 2010 · Жалоба Оптимизация кусков кода матлаба хорошо, но объясните мне пожалуйста как влияет это на реализацию в ПЛИС? Вопросы по написанию программы/модели в матлабе и реализации в ПЛИС - совершенно разные вопросы. То, что написано более просто и эффективно при том же уровне абстракции не только в матлабе, но хотя бы даже на бумаге в виде слов, поместится в ПЛИС пропорционально проще и эффективнее. Ведь фактически Muscat пишет поведенческую модель, а не функциональную, используя язык Матлаба. Мне кажется это совершенно очевидным, хотя могу и ошибаться. Но пока что моя практика имеет хорошую сходимость с этим тезисом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 18 сентября, 2010 Опубликовано 18 сентября, 2010 · Жалоба x736C, Да! Именно этим я сейчас и занимаюсь. Сначала написал модель просто, чтобы понять алгоритм, потом понял, что это модифицированная реализация методом Register Exchange, сейчас как раз написал модель повторяющую функционал того, что будет сделано в ПЛИС - BMU, блок ACS, TBU и память. Сейчас по ПЛИСу у меня вопрос какую память брать и как ее организовать с циклическим указателем адреса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться