Перейти к содержанию
    

Djony1987

1.Подход нормальный. Именно так и делают. Это знаковые решения с демодулятора.

2.В простейшем случае метрики вообще нормализировать не надо. Достаточно большой разрядности ACS. При необходимости можно просто "осадить" на несколько разрядов знаковым сдвигом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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];

 

Спаисбо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Djony1987

Как лучше виднее Вам (исходя из задачи). :)

Обычно, для практической реализации, квантование до 6-ти битных входных значений достаточно. В цитируемой Вами книги, IMHO, есть обоснование.

Поэтому, имеет смысл заложиться на 16 разрядов для метрики.

Метрики и пути, IMHO, удобнее хранить в BRAM.

Видимо, у Вас код (133,171). Для Вашего случая (для такой низкой скорости декодирования), как указал Grumbler_2002, всё уместится в одну BRAM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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?

 

Спасибо!

Изменено пользователем Djony1987

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Под 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

 

Спасибо!

Изменено пользователем Djony1987

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день

 

Есть следующий вопрос по реализации декодера Витерби.

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

Вопросы есть следующие

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 буфер, но с возможностью обращения к каждому элементу.

 

Спасибо!

Изменено пользователем Muscat

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день

 

Есть следующий вопрос по реализации декодера Витерби.

 

 

Спасибо!

Начинайте со структурно-функциональной схемы. Нарисуйте все цифровые модули и соединение между ними. Сперва какую-то обобщенную, потом более подробную. Опишите все функции, которые будет выполнять каждый модуль - тогда мысли упорядочатся.

Тогда появятся конкретные вопросы по реализации...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функциональную схему я нарисовал, модель в матлабе работает, еще я самостятельно кушаю и умею держать головку.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... как организовать память

Как взятую из «визарда» одно- или двухпортовую память с необходимой для вашего функционала обвязкой в виде дополнительной регистрово-комбинационной логики

 

... как правильно проэмулировать в матлабе сдвиговый регистр

Могу ошибаться в синтаксисе, но что-то вроде такого, может быть, подойдет:

for i = 1:n-1
       reg(i) = reg(i + 1)
end

Изменено пользователем x736C

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо!

Попробую еще раз объяснить, что я хочу. Обратившись к ячейке памяти 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

 

Вот эти преобразования десятичный-двоичный и занимают много времени. Есть мысль при моделировании вообще отказаться от сдвига и все операции проводить над десятичными числами

 

Изменено пользователем Muscat

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С утра соображается явно быстрее. Если кому интересно, то трейбек реализовался вот так

 

Код среды матлаб

     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 раз. Буду дальше работать над оптимизацией.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функциональную схему я нарисовал, модель в матлабе работает, еще я самостятельно кушаю и умею держать головку.

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

Вот читаю Ваши сообщения - не могу понять Вы не можете написать оптимизированную программу/модель в матлабе Декодера Витерби или Вам нужно реализовать этот Декодер Витерби в ПЛИС?

Если вопросы связанные с матлабом,тогда лучше задать их здесь

Если вопросы по ПЛИС - делитесь как Вы предполагаете перевести код матлаба в реализацию для ПЛИС (поэтому я и задал вначале такой вопрос). Оптимизация кусков кода матлаба хорошо, но объясните мне пожалуйста как влияет это на реализацию в ПЛИС? Вопросы по написанию программы/модели в матлабе и реализации в ПЛИС - совершенно разные вопросы.

 

Пока в таком варианте, с неглубоким трейбеком (5) и простым кодеком (3х(7 5)) 100k бит прогоняет за 16 секунд. Раньше на это требовалось около 2ух минут, ускорение почти в 10 раз. Буду дальше работать над оптимизацией.

На компьютере?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оптимизация кусков кода матлаба хорошо, но объясните мне пожалуйста как влияет это на реализацию в ПЛИС? Вопросы по написанию программы/модели в матлабе и реализации в ПЛИС - совершенно разные вопросы.

То, что написано более просто и эффективно при том же уровне абстракции не только в матлабе, но хотя бы даже на бумаге в виде слов, поместится в ПЛИС пропорционально проще и эффективнее. Ведь фактически Muscat пишет поведенческую модель, а не функциональную, используя язык Матлаба.

Мне кажется это совершенно очевидным, хотя могу и ошибаться. Но пока что моя практика имеет хорошую сходимость с этим тезисом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

x736C, Да! Именно этим я сейчас и занимаюсь. Сначала написал модель просто, чтобы понять алгоритм, потом понял, что это модифицированная реализация методом Register Exchange, сейчас как раз написал модель повторяющую функционал того, что будет сделано в ПЛИС - BMU, блок ACS, TBU и память.

 

Сейчас по ПЛИСу у меня вопрос какую память брать и как ее организовать с циклическим указателем адреса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...