Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Языки VHDL и VERILOG в проектировании цифровой аппаратуры

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
Глава 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;
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]