Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Scrambler
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
snayperAlfa
Здравствуйте. Хочу вот реализовать скремблер. Есть документ, описывающий его работу. Но мутный немного. особенно в планек счетчика. Я создал модель на VHDL, но выходная последовательность отличается от той что задана в документации. Подскажите где может быть баг пожалуйста.





Код
library IEEE;
use IEEE.std_logic_1164.all;


entity Scrambler_1 is
port (
    CLK: in std_logic;
    data_in: in std_logic;
    data_out: out std_logic;
    CLK_out:out std_logic
);
end entity;

architecture Scrambler_1 of Scrambler_1 is

signal STATE:integer:=0;

begin
    
    process(CLK)
        variable reg:std_logic_vector(19 downto 0):=(others =>'1');    
        variable a:std_logic;
        variable b:std_logic;
        variable c:std_logic;
        variable d:std_logic;
        variable e:std_logic;
        
        variable counter:integer;
    
    begin  
            
        if(CLK'event and CLK='1' ) then
            
            CASE STATE is
                
                when 0=>
                    CLK_out<='0';
                    
                    --Initial values;
                    reg(19 downto 0):=(others =>'1');
                    counter:=31;
                    
                    a:=reg(0) xor reg(8);
                    b:=reg(2) xnor reg(19);
                    
                    c:='0';
                    
                    d:=b xnor c;
                    e:=data_in xnor d;
                    data_out<=e;
                    
                    STATE<=1;
                
                when 1=>
                    e:=data_in xnor d;
                
                    CLK_out<='0';
                    --sdvig registra
                    reg(19 downto 1):=reg(18 downto 0);
                    reg(0):=e;
                    
                    a:=reg(0) xor reg(8);
                    b:=reg(2) xnor reg(19);    
                    
                    counter:=counter+1;
                    
                    if(a='1') then
                        counter:=31;
                    end if;
                    
                    if(counter=32) then
                        counter:=0;
                    end if;
                    
                    if(counter=30) then
                        c:='1';
                    else
                        c:='0';
                    end if;
                    
                    
                    
                    d:=b xnor c;
                    e:=data_in xnor d;
                    data_out<=e;
                    
                    STATE<=2;
                
                when 2=>
                    
                    CLK_out<='1';
                    STATE<=1;
                
                    
                when others => null;
                
            end case;

        end if;
    
    end process;
        
end architecture;



У меня получается последовательность: 0xFF,0xFF,0xFF,0xFD,0xB6,0xDB
SFx
У Вас с последовательность сдвинута на бит, и порядок бит в другом направлении в сдвиговый регистр проверки (из которого берете) скорее всего записываются...

вот моя реализация:
Нажмите для просмотра прикрепленного файла

Нажмите для просмотра прикрепленного файлаНажмите для просмотра прикрепленного файла
snayperAlfa
Спасибо, буду разбираться.

Можете написать пожалуйста, какова последовательность действий.
Сдвиг регистра, увеличение счетчика, вычисление функций XOR, XNOR. Также мне кажется странным описание счетчика.
SFx
Цитата(snayperAlfa @ Mar 19 2011, 13:48) *
Спасибо, буду разбираться.

Можете написать пожалуйста, какова последовательность действий.
Сдвиг регистра, увеличение счетчика, вычисление функций XOR, XNOR. Также мне кажется странным описание счетчика.


каждый такт clk при условии его разрешения clk_en происходит сдвиг регистра и инкремент счетчика (если s_sreg_xor='0', иначе счетчик сбрасывается) .
все остальные функции выполняются уже над значениям сдвигового регистра, значениями входа, и значением счетчика и изменения этих сигналов будут учитываться при сдвиг/инкременте уже на следующий такт clk.

счетчик описан на сумматоре, при его переполнение счет начинается с начала.
snayperAlfa
Я смотрю по диаграмме, что ваша последовательность выходная отличается:
По стандарту:0xFF,0xFF,0xFF,0x7F,0xDB.....
А у Вас: 0xFF,0xFF,0xFF,0x7F,0xBF....
SFx
смотрите сигнал в тестбенче sdout при sdout_val='1'
на картинке выделены жирным
snayperAlfa
Нажмите для просмотра прикрепленного файла


Напишу на смесе C и VHDL

Правильно ли я понимаю:

Код
Инициализация:
      REG="11111111111111111111";
      Counter=31;

      a=REG(0) xor REG(8);
      b=REG(2) xnor REG(19);

      c=0;
      d=c xnor b;
      e=d_in xnor d;



Рабочий режим:

1)  e=d_in xnor d;

2) REG = REG << 1;   //сдвиг влево = умножение на 2
3) REG(0)=e;

4)  if(a='1') then
            Counter=31;
     else
            Counter=Counter+1;
      end if;

5)   if(Counter=32) then
          Counter=0;
       end if;

6)  if(Counter=30) then
           c='1';
      else
           c='0';
      end if;

7)    a=REG(0) xor REG(8);
8)    b=REG(2) xnor REG(19);

9)    d=c xnor b;
10)   e=d_in xnor d;

11)Вывести значение "e"
12)Перейти к пункту п.1
SFx
вроде похоже.

только часть функции с пункта 1 до 12 должны происходит в момент возрастания фронта clk.

пункт 1 и 10 дублируются.


VHDL язык описания, а не алгоритмический. здесь сразу все действия (в алгоритмическом языке их принято называть присваиванием) происходят мгновенно (логика) или по фронту (спаду) тактового сигнала (регистр/триггер)

у Вас сложность наверное в том, что не можете понять, где в алгоритме операции которые нужно реализовать в логике, а которые в триггерах.
snayperAlfa
Насчет дублирования:

1) e=d_in xnor d; // тут значение до всех операций

10) e=d_in xnor d; //тут значение после всех операций xor,xnor. Оно ведь может отличаться от значения до операций сдвига,счетчика....

11)Вывести значение "e" //Поэтому принимаем вот это значение за результат


Данный скремблер я буду реализовывать на C, а на VHDL пока моделирую что-бы понять правильность работы. Да и с битами на VHDL удобней работать. В конечном итоге у меня будет полностью последовательный код.
AndrewS6
Цитата
5) if(Counter=32) then
Counter=0;
end if;

Вот это место сильно смущает. По логике работы скремблера, счетчик вообще не должен принимать значение 32.
snayperAlfa
Завтра на работе проверю
snayperAlfa
Вот запустил это на С:

Код
//слева в выводе младший бит


#include <iostream>
using namespace std;

unsigned long data_in=0;

unsigned long counter=31; //5-bit counter; Initial value
unsigned long reg=1048575; //(2^20)-1  20-bit register; Initial value

unsigned long a;
unsigned long b;
unsigned long c;
unsigned long d;
unsigned long e;

//Функция которая возвращает значение бита в слове
unsigned long bit10(unsigned long data,unsigned long bit_number);

//Процедура которая возращает 1 если Счетчик==30
//или 0 если Счетчик!=30
unsigned long outc(void);

//процедура которая инкрементирует счетчик
void counter_inc(void);

int k=0;

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!


    //Initial values
    counter=31; //5-bit counter; Initial value
    reg=0b11111111111111111111; //(2^20)-1  20-bit register; Initial value

    a = bit10(reg,0) ^ bit10(reg,8);
    a=bit10(a,0);

    b = ~(bit10(reg,2) ^ bit10(reg,19));
    b=bit10(b,0);

    c = outc();

    d=~(b^c);
    d=bit10(d,0);

    e=~(data_in ^ d);
    e=bit10(e,0);


    for(int i=0;i<64;i++){
        //State 0

            e=~(data_in ^ d);
            e=bit10(e,0);

            reg=reg<<1;
            reg=reg|e;

            counter_inc();
            c = outc();

            a = bit10(reg,0) ^ bit10(reg,8);
            a=bit10(a,0);

            b = ~(bit10(reg,2) ^ bit10(reg,19));
            b=bit10(b,0);

            d=~(b^c);
            d=bit10(d,0);

            //e=~(data_in ^ d);
            //e=bit10(e,0);

            cout<<e;
            k++;
            if(k==8){k=0;cout<<'\n';}
    }
    return 0;
}


//Функция которая возвращает значение бита в слове
unsigned long bit10(unsigned long data,unsigned long bit_number)
{
    if((data & (1<<bit_number))>0) {return 1;}
    else{return 0;}
};


//Процедура которая возвращает 1 если Счетчик==30
//или 0 если Счетчик!=30
unsigned long outc(void)
{
    if(counter==30){return 1;}else{return 0;};
};


void counter_inc(void)
{
    if(a==1){
        counter=31;
    }
    else{
        if(counter==31){
            counter=0;
        }
        else
        {
            counter=counter+1;
        }
    };
};


Баг в том,что сначала выводится младший бит. То есть, слева младший бит.
В результате выдало следующее:

Код
Слева МЛДАШИЙ бит!

!!!Hello World!!!
11111111  =0xFF
11111111  =0xFF
11111111  =0xFF
11111110  =0x7F
11011011  =0xDB
01101101  =0xB6
10100110  =0x65
10011010  =0x59


Теперь надо понять почему слева младший бит, а не старший. Или так и должно быть. В стандарте там описано последовательность байтов, а не битов.
snayperAlfa
Кажеться разобрался.
Надо перестать использовать слово байт, а перейти на бит. И использовать термин - поток битов. Тогда всё становится более понятно sm.gif

Спасибо, SFX sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.