Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Языки VHDL и VERILOG в проектировании цифровой аппаратуры
.pdf
Глава 5. Синтезабельность HDL-описаний 171
assign #(1) O = I; assign true = 1'b1;
assign false = 1'b0;
endmodule /* IBUF */
// ОПУЩЕН module LUT4_4F7F ( I0, I1, I2, I3, O);
//НИЖЕ триггер со сбросом----------------------------------------module FDR ( Q, D, C, R);
output Q;input D;input C;input R;
wire Q ;wire D ;wire C ;wire R ;
wire ri ;wire fbr ;
assign #(1) ri=~R;
assign #(1) fbr = ri & D ;
reg r_e_g2; // dff
always @(posedge C) r_e_g2 = #1 fbr ;
assign Q = r_e_g2;
endmodule /* FDR */
// ОПУЩЕН module LUT4_FCFB ( I0, I1, I2, I3, O);
// ОПУЩЕН module LUT2_2 ( I0, I1, O);
// ОПУЩЕН module LUT2_4 ( I0, I1, O);
input I0;input I1;
//НИЖЕ АВТОМАТ СОСТОЯНИЙ - 2 триггера и управление ----------module cell_svet_state_3_0__h ( svet_state,
rst_c, clk_c, N_76, N_60, G_52, N_11_1, N_12_1);
output [1:0] svet_state;
input rst_c;input clk_c;input N_76;input N_60;input G_52;
output N_11_1;output N_12_1;
wire [1:0] svet_state;wire rst_c ;wire clk_c ;wire N_76 ;
wire N_60 ;wire G_52 ;wire N_11_1 ;wire N_12_1 ;
wire [0:0] svet_state_ns_0_iv_i;wire N_36_i_0 ;
// @1:62
LUT4_4F7F N_36_i (.I0(G_52),.I1(svet_state[1]),
.I2(svet_state[0]),.I3(N_60), .O(N_36_i_0));
// @1:62
FDR \svet_state_Z[0] (.Q(svet_state[0]),
.D(svet_state_ns_0_iv_i[0]),.C(clk_c), .R(rst_c));
// @1:62
FDR \svet_state_Z[1] (.Q(svet_state[1]),
.D(N_36_i_0),.C(clk_c), .R(rst_c));
// @1:62
LUT4_FCFB \svet_state_ns_0_iv_i_0[0] (
.I0(N_60), .I1(svet_state[0]),
.I2(N_76), .I3(svet_state[1]),
.O(svet_state_ns_0_iv_i[0]));
// @1:62
LUT2_2 svet_state_tr2_1_0_and2 (.I0(svet_state[0]),
.I1(svet_state[1]), .O(N_11_1));
// @1:62
LUT2_4 svet_state_tr3_6_1_0_and2 (
.I0(svet_state[0]), .I1(svet_state[1]),
.O(N_12_1));
endmodule /* cell_svet_state_3_0__h */
// ОПУЩЕН module LUT4_0100 ( I0, I1, I2, I3, O);
// НИЖЕ СВЕТОФОР------------------------ СВЯЗИ КОМПОНЕНТ --------

172 Глава 5. Синтезабельность HDL-описаний
module simple_svetofor2 ( clk, rst, red,
green, yellow);
input clk;input rst;
output red;output green;output yellow;
wire clk ;wire rst ;wire red ;wire green ;
wire yellow ;wire [3:3] svet_state_d;
wire [1:0] \svet_state_h.svet_state ;
wire [6:0] count;
wire N_11_1 ;wire N_12_1 ;wire N_57 ;
wire N_76 ;wire N_60 ;wire N_85_1 ;
wire G_54 ;wire G_52 ;wire rst_c ;wire clk_c ;
wire cnt_rst ;wire VCC ;wire GND ;
// @1:62
GND GND_Z ( .G(GND));
// @1:62
LUT2_8 G_32 (.I0(\svet_state_h.svet_state [0]),
.I1(\svet_state_h.svet_state [1]),
.O(svet_state_d[3]));
// @1:62
LUT4_0040 G_33 (.I0(count[2]),
.I1(count[1]),.I2(count[0]),.I3(N_57),.O(N_76));
// @1:62
LUT4_FFFE G_37 (.I0(count[3]),.I1(count[4]),
.I2(count[5]),.I3(count[6]), .O(N_57));
// @1:62
LUT4_FDFF G_40 (.I0(count[0]),.I1(N_57),
.I2(count[1]),.I3(count[2]),.O(N_60));
// @1:62
LUT3_EA G_54_Z (.I0(N_85_1),.I1(G_52),
.I2(svet_state_d[3]),.O(G_54));
// @1:62
LUT4_0D5D G_54_1 (.I0(\svet_state_h.svet_state [1]),.I1(N_76),
.I2(\svet_state_h.svet_state [0]), .I3(N_60),
.O(N_85_1));
// @1:62
VCC VCC_Z (.P(VCC));
// @1:15
BUFGP clk_ibuf ( .I(clk),
.O(clk_c));
//НИЖЕ КОНКРЕТИЗАЦИЯ СЧЕТЧИКА-----------------------------// @1:29
count_up_7 cnt (
.count({count[6], count[5], count[4], count[3],
count[2], count[1], count[0]}),
.cnt_rst(cnt_rst),.clk_c(clk_c));
//НИЖЕ триггер сброса счетчика---------------------------------// @1:62
FDS cnt_rst_Z (.Q(cnt_rst),.D(G_54),
.C(clk_c),.S(rst_c));
//НИЖЕ выход на внешние контакты кристалла----------------// @1:16
OBUF green_obuf (.O(green),.I(N_12_1));

Глава 5. Синтезабельность HDL-описаний 173
// @1:16
OBUF red_obuf (.O(red), .I(N_11_1));
// @1:15
IBUF rst_ibuf (.O(rst_c), .I(rst));
// @1:62---Управление состоянием автомата
cell_svet_state_3_0__h svet_state_h (
.svet_state({\svet_state_h.svet_state [1],
\svet_state_h.svet_state [0]}),
.rst_c(rst_c),.clk_c(clk_c),
.N_76(N_76),.N_60(N_60),
.G_52(G_52),.N_11_1(N_11_1),
.N_12_1(N_12_1));
// @1:62
LUT4_0100 \un1_un1_rst_i_0_and2_1.G_52 (
.I0(N_57),.I1(count[0]),.I2(count[2]),
.I3(count[1]), .O(G_52));
// @1:16
OBUF yellow_obuf ( .O(yellow), .I(svet_state_d[3])
);
endmodule /* simple_svetofor2 */
Вопросы и упражнения
1. Как реализован счетчик в светофоре — с помощью сумматора или как счет-
чик с последовательным переносом?
2. При моделировании будущее состояние светофора next_svet_state порой меняется нечетко (хотя конечное svet_state верно). Не является ли это следствием
обычного кодирования состояний, может, противогоночное кодирование улучшит
картину?
Вопросы к главе 5
1. Какие параметры и критерии обычно надо задать системе синтеза?
2. В каких случаях синтезатор порождает нежелательные триггеры-защелки?
3. Почему рекомендуется иметь регистры на выходах проектируемых блоков?
4. К чему приводит неполный список чувствительности процессов при верификации и как это влияет на результаты синтеза?

Глава 6. Реализация шифроалгоритма
RC4 íà ÏËÈÑ
Данная глава иллюстрирует подходы к проектированию устройств на HDL.
В нее включены результаты курсовой работы студентов МЭИ, которые схемно реализовали шифроалгоритм RC4 базе ПЛИС серии VIRTEX фирмы XILINX.
6.1. Шифроалгоритм RC4
Шифроалгоритм RC4 был предложен одним из отцов современной криптографии профессором Риверстом (Riverst). Oн широко используется наряду с другими шифроалгоритмами в Netscape и других Интернет-браузерах. Описание RC4
автор взял из опубликованной в Интернет статьи, посвященной сравнительной
оценке эффективности схемной и программной (на PC) реализации систем взлома шифроалгоритмов (www.cs.berkley.edu/~iang/isaac/hardware). Оно совпадает с
приведенным в [21] описанием RC4.
Шифроалгоритм RC4 предполагает наличие 256-байтной постоянной памяти
ключей К (в случае, если, как обычно, ключ имеет длину меньше 256 байт, его дополняют до 256 повторением), 256-байтной рабочей памяти S с произвольным
доступом и двух 8-разрядных регистровiиj.
Работа начинается с инициализации ключом рабочего массива S
j=0
fori=0to255 //заполнение ячеек S
S(i) = i // их адресами
fori=0to255
j= (j + S(i) + K(i))mod 256
swap S(i) and S(j) // обмен S(i) и S(j)
После этогоiиjустанавливаются в 0.
Как только инициализация ключом массива S закончена, возможно побайтовое шифрование (дешифрование) поступающих данных по следующему алгоритму.
Сначала извлекается байт рабочего ключа (output)
i=(i+1)mod256
j = (j + S(i)) mod 256
swap S(i) and S(j)
output S(S(i) + S(j)) mod 256
Извлеченный из памяти S на выход (output) байт рабочего ключа складывается по модулю 2 (XOR) с шифруемым (дешифруемым) байтом данных и образует
шифрокод (дешифрокод).
Ниже приведена найденная в Интернет спецификация алгоритма на языке
PERL.
#!/usr/bin/perl -0777
@k=unpack('C*',pack('H*',shift));for(@t=@s=0..255){$y=($k[$_%@k]+$s[$x=$_
]+$y)%256;&S}$x=$y=0;for(unpack('C*',)){$x++;$y=($s[$x%=256]+$y)%256;
&S;print pack(C,$_^=$s[($s[$x]+$s[$y])%256])}sub S{@s[$x,$y]=@s[$y,$x]}

Глава 6. Реализация шифроалгоритма RC4 на ПЛИС 175
Авторы программы пишут, что проверяли ее на тексте «test message», используя 32-разрядный шестнадцатеричный ключ «12abcdef» (закодированное сообщение перенаправлялось в файл «test.rc4» таким способом: % echo test message | rc4
12abcdef > test.rc4).
При дешифровании процесс был обратный и использовался тот же ключ и закодированный файл % rc4 12abcdef < test.rc4.
Эквивалентный С код программы RC4 приводится ниже. Eго можно отыскать
на многих сайтах, например ftp://ftp.ox.ac.uk /pub/crypto/misc/rc4.tar.gz
Версия С-программы (автор John Allen).
#define S ,t=s[i],s[i]=s[j],s[j]=t /* rc4 hexkey <file */
unsigned char k[256],s[256],i,j,t;main(c,v,e)char**v;{++v;while(++i)s[
i]=i;for(c=0;*(*v)++;k[c++]=e)sscanf((*v)++-1,"%2x",&e);while(j+=s[i]
+k[i%c]S,++i);for(j=0;c=~getchar();putchar(~c^s[t+=s[i]]))j+=s[++i]S;}
Запуск программы: % rc4 hexkey < input > output
Компиляция: % gcc -o rc4 -O4 rc4.c
Ниже — цитата из Интернет-статьи (www.cs.berkley.edu/~iang/isaac/hardware),
посвященной шифроалгоритму RC4.
«SSL, одна из известных систем шифрования, является несколько усложненной версией RC4. Вместо простой переписи ключа в массив К при инициализации он сначала обрабатывается xeш-функцией MD5, и результат MD5 записывается в К. Так как запись и выборка из К осуществляется в строго определенном порядке, его схемная реализация необязательно требует памяти
произвольного доступа. Пусть память — самый медленный блок устройства.
Подсчитаем число обращений к памяти, необходимых для инициализации ключа. Первый цикл — 256 обращений, каждый шаг второго цикла — 4 обращения. Всего инициализация требует 1281 обращение. Аналогично, обработка
каждого шифруемого байта данных требует 5 обращений в память». Авторы вышеприведенной статьи реализовали схему шифроалгоритма RC4 на ПЛИС фирмы Альтера, а память в виде подсоединенного блока внешней памяти с циклом
10 ns. В ходе сопоставлений возможностей реализованного ими аппаратного
подхода и программного, на базе использования простаивающих в праздничные
дни и ночи сетей организаций, они сделали вывод в пользу программного по
цене стоимость — производительность.
На базе приведенных описаний можно составить спецификацию шифроалгоритма RC4 на HDL. Это описание предполагалось использовать при совместном
моделировании с синтезабельным RTL-описанием и потом при совместном моделировании с результатами синтеза — схемным решением на базе ПЛИС типа
FPGA серии VIRTEX фирмы XILINX.
Упражнения
1. Проверьте соответствие PERL- и С-спецификаций RC4.
2. Является ли тест, предложенный авторами PERL- и С-программ, полным и
как его улучшить?

176 Глава 6. Реализация шифроалгоритма RC4 на ПЛИС
6.2. HDL-спецификация алгоритма RC4
Так как в дальнейшем предполагалось использовать HDL-спецификацию как
эталон при верификации схемной реализации RC4, в нее добавлены два сигнала — ask и ready. По первому (ask ) начинается инициализация ключом массива
памяти. Когда инициализация закончена и устройство готово, оно выдает сигнал
ready и может работать в режиме приема (по фронту сигнала strobe) очередного
входного байта (code_in) и его шифрования (дешифрования) с результатом в
code_out.
6.2.1. Verilog
VERILOG-спецификация
Основное отличие от эталона — остаток массива К заполняется нулями при
длине ключа, меньшей 256.
module RC4_specification (ask, ready,strobe, code_in, code_out);
parameter n=256; parameter debug=1;
input ask,strobe; input [7:0] code_in;
output ready; output [7:0] code_out;reg [7:0] code_out;
integer i, j;reg [7:0] tmp;reg[7:0] tmp_out;
reg ready;reg [7:0] S [0:255]; reg [7:0] K [0:255];
initial begin // инициализация K, S массивов
ready=0; j=0;
for (i=n;i<=255;i=i+1) K[i]=0;// массив K заполняется 0
@(posedge ask) ;
// ниже чтение ключа из файла key_file.txt в К,
// ключ в шестнадцатеричном коде
$readmemh ("key_file.txt", K,0,n-1);//ниже контрольная печать ключа
if(debug)
for (i=0;i<=n-1;i=i+1) $display("check key file i=%0d,K[i]=%0d",
i,K[i]); // ниже инициализация S
for (i = 0; i <= 255; i = i+1) S[i] = i;
for (i=0; i <= 255; i = i+1) begin
j = (j+S[i] + K[i]) % 256; // % деление по модулю - остаток
tmp = S[i];
if(debug)
$display("tmp=%b",tmp);
S[i] = S[j]; S[j] = tmp;
if(debug)
$display("i=%d,s[i]=%b,j=%d, s[j]=%b",i,S[i],j,S[j]);
end
ready=1;j=0;
end
/* //Простой тест- массив S заполнен числами 0-255
for (i = 0; i <= 255; i = i+1) begin
S[i] = i;
if(debug)
$display("i=%d, S[i]=%d ",i,S[i] );
end
#10; ready =1; j=0; end

Глава 6. Реализация шифроалгоритма RC4 на ПЛИС 177
*/
// ниже работа
always @ (posedge strobe) begin
i = (i+1) % 256;
j= (j+S[i]) % 256;
tmp = S[i];
if(debug)
$display("i=%d j=%0d S[i]=%0d S[j]= %d", i,j,S[i],S[j]);
S[i] = S[j];
S[j] = tmp;
tmp_out = S[(S[i] + S[j]) % 256];
if(debug)
$display("tmp_out=%0b",tmp_out);
code_out = code_in ^ tmp_out;
end
endmodule //RC4_spec.
module tb_spec_ver_check;
parameter code_in= 8'b00001111;parameter n=3;
reg ask,strobe;wire ready; wire [7:0] code_out;
RC4_specification #(n) uut (ask, ready,strobe, code_in, code_out);
initial begin
#10;ask=1;strobe=0;
wait (ready==1);$display("READY was");
repeat(20)
begin #10;strobe =1;#10;strobe=0;
#10; $display ("code_out=%h, t=%0t",code_out,$time);
end
$finish;
end
endmodule
Òåñò
Ниже приведен пример модуля тестирующей программы (tb_spec_ver_check),
файла с ключем (key_file.txt) и листинг первых 5 циклов работы в режиме шифрирования. Тестирование проводилось на двух примерах — в одном варианте массив
S заполнялся числами 0—255 (это упрощало расчет эталона вручную), в другом в
файле первые три байта ключа имели значения 1, 2, 3, а остальные 0.
module tb_spec_ver_check;
parameter code_in= 8'b00001111;parameter n=3;
reg ask,strobe;wire ready; wire [7:0] code_out;
RC4_specification #(n) uut (ask, ready,strobe, code_in, code_out);
initial begin
#10;ask=1;strobe=0;
wait (ready==1);$display("READY was");
repeat(20)
begin #10;strobe =1;#10;strobe=0;
#10; $display ("code_out=%h, t=%0t",code_out,$time);
end
$finish;
end
endmodule

178 Глава 6. Реализация шифроалгоритма RC4 на ПЛИС
Файл ключа key_file.txt
1 //K[0]
2 //K[1]
3 //K[2]
Фрагмент листинга вывода
READY was
i= 1 j=4 S[i]=4 S[j]= 250
tmp_out=10110001
code_out=be, t=40
i= 2 j=229 S[i]=225 S[j]= 41
tmp_out=11111001
code_out=f6, t=70
i= 3 j=152 S[i]=179 S[j]= 131
tmp_out=10001111
code_out=80, t=100
i= 4 j=156 S[i]=4 S[j]= 202
tmp_out=11100110
code_out=e9, t=130
i= 5 j=58 S[i]=158 S[j]= 168
6.2.2. VHDL
VHDL-спецификация
Она развернута в тест проверки алгоритма на простом ключе и с печатью промежуточных результатов.
library IEEE;
use IEEE.std_logic_1164.all;
entity RC4_specification is
port(ask:in std_logic;
ready:out std_logic;
strob:in bit;
code_in:in std_logic_vector(7 downto 0);
code_out:out std_logic_vector(7 downto 0));
end RC4_specification;
library IEEE;
use std.textio.all;use IEEE.std_logic_textio.all;
use IEEE.std_logic_unsigned.all;use IEEE.std_logic_arith.all;
architecture behaviour of RC4_specification is
type memory is array(0 to 255 )of std_logic_vector(7 downto 0);
shared variable K,S:memory;
signal tmp_out:std_logic_vector(7 downto 0);
begin
--key initialization array K
start_proc:process(ask)
variable i,j:natural:=0;
variable tmp:std_logic_vector(7 downto 0);
variable str:line;
begin

Глава 6. Реализация шифроалгоритма RC4 на ПЛИС 179
------------------Подготовка ключа----------------------if(strob='0')and(ask='1') then
ready<='0'; report "ready set to 0";
--Заполняем S последовательно значениями от 0 до 255
foriin0to255loop
S(i):=CONV_STD_LOGIC_VECTOR(i,8);
end loop;
---------------------- некоторое значение ключа-----------
K(0):="00000001"; K(1):="00000010"; K(2):="00000011";
foriin3to255loop
K(i):="00000000";
end loop;
----------------------------------------------------------
write(str,"START-S initialisation");
foriin0to255loop
--каждый очередной элемент S обменивается местами с элементом
--номер которого определяется элементом ключа key
--самим элементом и суммой номеров элементов, с которыми
-- происходил обмен на предыдущих итерациях
j:=(j+CONV_INTEGER(S(i))+CONV_INTEGER(K(i)))mod 256;
tmp:=S(i);
write(str," i= ");write(str,i,right,0); write(str," S(I)= ");
write(str,s(i),right,0);
S(i):=S(j);
write(str," j=");write(str,j,right,0);write(str," S(j)= ");
write(str,s(j),right,0); writeline(output,str);
S(j):=tmp;
end loop;
--закоментирован простой тест с S(i)=i
--for i in 0 to 255 loop S(i):= conv_std_logic_vector(i,8); end loop;
ready<='1';
write(str," READY SET TO ! "); writeline(output,str);
end if;
end process start_proc;
---------------------шифрование--------------------------
code_process:process(strob)
--с code_in тоже самое получается
variable i,j:natural:=0;variable tmp:std_logic_vector(7 downto 0);
variable code_tmp:std_logic_vector(7 downto 0);variable str:line;
begin
write( str,"START CODING "); writeline(output,str);
if strob'event and strob='1' then
i:=(i+1)mod 256;
j:=(j+CONV_INTEGER(S(i)))mod 256;
tmp:=S(i);
write(str," i= ");write(str,i,right,0);
write(str," S(i)= "); write(str,s(i),right,0); writeline(output,str);
S(i):=S(j);
write(str," j= "); write(str,j,right,0);
write(str," S(J)= "); write(str,s(j),right,0); writeline(output,str);
S(j):=tmp;

180 Глава 6. Реализация шифроалгоритма RC4 на ПЛИС
code_tmp:=S((conv_integer(S(i))+conv_integer(S(j)))mod 256);
tmp_out <=code_tmp;
write( str," code_tmp= ");write(str,code_tmp,right,0); writeline(output,str);
code_out<=code_in xor code_tmp;
end if;
end process;
end;
Òåñò RC4_coder
--Подключение библиотек
library IEEE;
use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;
use IEEE.std_logic_textio.all;use std.textio.all;
entity test_bench_RC4 is
end;
architecture behaviour of test_bench_RC4 is
signal ask,ready,clk,rst:std_logic;signal out_of_code:std_logic;
signal code_in,code_out:std_logic_vector(7 downto 0);
signal strob:bit;
--Описание тестируемого кодера RC4
begin
coder:entity RC4_specification
port map(ask,ready,strob,code_in,code_out);
--Тестовый набор
test:process
variable i:integer:=0;variable counter:integer;variable str:line;
type t_data is array (1 to 10) of std_logic_vector(7 downto 0);
constant data:t_data:=(( "00000001"),("00000010"),("00000011"),
("00000100"),("00000101"), ("00000110"),("00000111"),("00001000"),
("00001001"),("00001010"));
--constant data:t_data:=(("00000000"),("00000001"),("00000010"),("00000011"));
begin
--Кодирование массива данных data
strob<='0';wait for 200 ns;
ask<='1'; --начало инициализации
wait for 200 ns;
ask<='0'; report"wait until ready='1'";write(str,ready); writeline (output,str);
--wait until ready='1';report "READY WAS";
wait for 200 ns;
for counter in 1 to 10 loop
-- code_in<=data( counter );--переменный код на входе
code_in<="00001111";--постоянный код на входе
wait for 200 ns; strob<='1'; wait for 200 ns;
write(str, "Input Information- code-in= ") ; write(str,code_in,right,0);
write(str, "Output Code Information =");write(str,code_out,right,0);
writeline(output,str);
strob<='0';
end loop;
wait;
end process;
end;
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
