├── README.md
├── bin
├── dst40
├── dst40.rbf
└── dst40test
├── dst40.qpf
├── dst40.qsf
├── dst40.sdc
├── software
├── dst40
│ ├── .cproject
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.core.resources.prefs
│ ├── dst40.c
│ ├── keyboard.c
│ └── keyboard.h
└── dst40test
│ ├── .cproject
│ ├── .project
│ ├── .settings
│ ├── org.eclipse.cdt.codan.core.prefs
│ └── org.eclipse.core.resources.prefs
│ ├── dst40.c
│ ├── dst40test.c
│ └── keyboard.c
└── source
├── Block64.v
├── Fa.v
├── Fb.v
├── Fc.v
├── Fd.v
├── Fe.v
├── Fg.v
├── Fh.v
├── KernelXX.v
├── conv.bat
├── dst40.v
├── dst40_XX.v
├── opt.txt
├── pll.qip
├── pll.v
├── pll
├── pll_0002.qip
└── pll_0002.v
└── soc_system.qsys
/README.md:
--------------------------------------------------------------------------------
1 | Инструкция по компиляции/использованию.
2 |
3 | В директории bin уже лежат скомпилированные файлы прошивки и программы.
4 | Можно их загружать и запускать.
5 |
6 | Если же есть желание внести изменения в прошивку или программу - ниже
7 | приведена подробная инструкция - как это сделать.
8 |
9 | Проект компилируется в Quartus II v14.0 и ARM DS-5. В других IDE
10 | не проверялось.
11 |
12 | Компиляция прошивки для FPGA:
13 |
14 | 1. Открываем файл проекта dst40.qpf в Quartus-е.
15 | 2. Запускаем Qsys: меню Tools -> Qsys.
16 | 3. Открываем проект Qsys: меню File -> Open -> входим в папку "source"
17 | и выбираем в ней файл "soc_system.qsys".
18 | 4. Закрываем окно "Open System Completed".
19 | 5. Запускаем генерацию HDL-файлов: нажимаем кнопку "Generate HDL..."
20 | в нижнем правом углу окна, а затем кнопку "Generate" в следующем
21 | открывшемся окне. Через некоторое время процесс завершится с парой
22 | предупреждений - игнорируем их. Закрываем окно "Generate Completed"
23 | и Qsys.
24 | 6. Запускаем компиляцию прошивки FPGA: меню Processing -> Start Compilation.
25 | Минут через 15 компиляция завершится с гигантским количеством
26 | предупреждений (446 в моём случае) - игнорируем их.
27 | 7. Закрываем Quartus.
28 | 8. Заходим в папку source и запускаем файл conv.bat - в результате
29 | в папке output_files создастся файл dst40.rbf.
30 | В bat-файле используется прямой путь до утилиты quartus_cpf.exe - если
31 | у Вас не такой - исправьте его на нужный.
32 |
33 | Компиляция программы dst40:
34 |
35 | 1. Запускаем Eclipse из состава IDE ARM DS-5.
36 | 2. Открываем проект: меню File -> Import -> General -> Existing Projects into
37 | Workspace. Нажимаем Next.
38 | 3. В открывшемся окне Import справа от поля "Select root directory" нажимаем
39 | кнопку "Browse..." и выбираем папку software/dst40. Нажимаем кнопку
40 | "Finish".
41 | 4. Выбираем активную конфигурацию: кликаем правой кнопкой мышки по названию
42 | проекта dst40 в окне "Project Explorer", выбираем в открывшемся меню
43 | пункты "Build Configurations" -> "Set Active" -> Release.
44 | 5. В конфигурации проекта используются полные пути до папок с инклудами.
45 | Проверьте, что они ведут правильно: меню Project -> Properties.
46 | В окне свойств слева переходим по пунктам "C/C++ Build" -> Settings.
47 | В закладке "Tool Settings" переходим по пунктам "GCC C Compiler 4
48 | [arm-linux-gnueabihv]" -> Includes и проверяем правильность путей
49 | к папкам "embedded/ip/altera/hps/altera_hps/hwlib/include"
50 | и "embedded/ip/altera/hps/altera_hps/hwlib/include/soc_cv_av"
51 | из состава ARM DS-5.
52 | 5. Компилируем программу: меню Project -> "Build All". Программа должна
53 | скомпилироваться без предупреждений/ошибок. В результате в папке
54 | software/dst40/Release должен появиться файл dst40 без расширения,
55 | размером около 500 килобайт. Это и есть программа.
56 |
57 | Использование:
58 |
59 | 1. Копируем файлы dst40.rbf и dst40 на MicroSD-карточку DE0-Nano-SoC
60 | в домашнюю директорию. Сделать это можно, например, с помощью SFTP-плагина
61 | для Total Commander.
62 | 2. Подключаемся к DE0-Nano-SoC терминалкой по SSH-каналу.
63 | 3. Заходим в домашнюю директорию.
64 | 4. Загружаем прошивку в FPGA: cat dst40.rbf > /dev/fpga0
65 | 5. Меняем права программе: chmod 744 dst40
66 | 6. Запускаем программу: ./dst40
67 | 7. Вводим исходные данные, проверяем их, если всё корректно - отвечаем "Y".
68 | 8. Ждём завершения поиска.
69 |
70 |
71 | ДИСКЛЕЙМЕР:
72 |
73 | Все исходники раздаются "как есть". Используйте их на собственный
74 | страх и риск. Если Вы с их помощью как-нибудь себе навредили (испортили
75 | настроение, сожгли отладочную плату, взорвали автомобиль и т.д. и т.п.),
76 | то я за это никакой ответственности не несу.
77 |
--------------------------------------------------------------------------------
/bin/dst40:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jok40/dst40/5bb41f7e69c89ec30772681651a57cab8a45c03c/bin/dst40
--------------------------------------------------------------------------------
/bin/dst40.rbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jok40/dst40/5bb41f7e69c89ec30772681651a57cab8a45c03c/bin/dst40.rbf
--------------------------------------------------------------------------------
/bin/dst40test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jok40/dst40/5bb41f7e69c89ec30772681651a57cab8a45c03c/bin/dst40test
--------------------------------------------------------------------------------
/dst40.qpf:
--------------------------------------------------------------------------------
1 | # -------------------------------------------------------------------------- #
2 | #
3 | # Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
4 | # Your use of Altera Corporation's design tools, logic functions
5 | # and other software and tools, and its AMPP partner logic
6 | # functions, and any output files from any of the foregoing
7 | # (including device programming or simulation files), and any
8 | # associated documentation or information are expressly subject
9 | # to the terms and conditions of the Altera Program License
10 | # Subscription Agreement, the Altera Quartus II License Agreement,
11 | # the Altera MegaCore Function License Agreement, or other
12 | # applicable license agreement, including, without limitation,
13 | # that your use is for the sole purpose of programming logic
14 | # devices manufactured by Altera and sold by Altera or its
15 | # authorized distributors. Please refer to the applicable
16 | # agreement for further details.
17 | #
18 | # -------------------------------------------------------------------------- #
19 | #
20 | # Quartus II 64-Bit
21 | # Version 14.0.0 Build 200 06/17/2014 SJ Full Version
22 | # Date created = 19:17:14 August 07, 2015
23 | #
24 | # -------------------------------------------------------------------------- #
25 |
26 | QUARTUS_VERSION = "14.0"
27 | DATE = "19:17:14 August 07, 2015"
28 |
29 | # Revisions
30 |
31 | PROJECT_REVISION = "dst40"
32 |
--------------------------------------------------------------------------------
/software/dst40/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
86 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/software/dst40/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | dst40
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
25 |
26 |
27 |
--------------------------------------------------------------------------------
/software/dst40/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=UTF-8
3 |
--------------------------------------------------------------------------------
/software/dst40/dst40.c:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *
3 | * Программа для поиска ключа DST40.
4 | *
5 | * Программа заточена под четырёхъядерный вариант модуля.
6 | *
7 | *----------------------------------------------------------------------------
8 | *
9 | * Аппаратная часть модуля DST40 соединена с HPS через мост HPS-to-FPGA.
10 | *
11 | * Адресная карта модуля DST40 (четырёхъядерный вариант):
12 | *
13 | * 0x00 - challenge ( 40 бит, Чтение/Запись ) Первый запрос
14 | * 0x08 - response ( 24 бита, Чтение/Запись ) Первый ответ
15 | * 0x10 - start_key ( 40 бит, Чтение/Запись ) Ключ, с которого начинать поиск
16 | * 0x18 - run ( 1 бит, Чтение/Запись ) Флаг запуска поиска
17 | * 0x20 - флаги:
18 | * бит 0 - key_found_w ( 1 бит, Только чтение ) Флаг "ключ найден"
19 | * бит 8 - key_not_found_w ( 1 бит, Только чтение ) Флаг "ключ не найден"
20 | * 0x28 - key ( 38 бит, Только чтение ) Найденный ключ (младшие биты)
21 | * 0x30 - kernels ( 4 бита, Только чтение ) Флаги ядер, нашедших ключ
22 | *
23 | *****************************************************************************/
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include "hwlib.h"
33 | #include "socal/socal.h"
34 | #include "socal/hps.h"
35 | #include "socal/alt_gpio.h"
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include "keyboard.h"
43 |
44 |
45 | //#############################################################################
46 | // ОПРЕДЕЛЕНИЯ
47 |
48 | // Адреса регистров в схеме DST40
49 |
50 | #define DST40_CHALLENGE (_h2f_base+0)
51 | #define DST40_RESPONSE (_h2f_base+8)
52 | #define DST40_START_KEY (_h2f_base+16)
53 | #define DST40_RUN (_h2f_base+24)
54 | #define DST40_FLAGS (_h2f_base+32)
55 | #define DST40_KEY (_h2f_base+40)
56 | #define DST40_KERNELS (_h2f_base+48)
57 |
58 |
59 |
60 | //#############################################################################
61 | // ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
62 |
63 | int _dst40_regs_file = 0;
64 | int _irq_ctrl_file = 0;
65 | void* _h2f_base = 0;
66 |
67 |
68 |
69 | /******************************************************************************
70 | * Callback-обработчик кода Ctrl+C - для корректного завершения
71 | * работы программы.
72 | *****************************************************************************/
73 |
74 | void exitToLinux( int sig )
75 | {
76 | if( sig != SIGINT )
77 | return;
78 |
79 | if( _h2f_base )
80 | {
81 | alt_write_dword( DST40_RUN, 0 ); // Останавливаем FPGA
82 |
83 | if( munmap( _h2f_base, 1024 ) != 0 ) // Размапливаем регистры модуля DST40
84 | printf( "\nERROR: munmap() failed...\n" );
85 | }
86 |
87 | if( _dst40_regs_file > 0 ) // Закрываем файл маппера,
88 | close( _dst40_regs_file ); // если он был открыт
89 |
90 | if( _irq_ctrl_file > 0 ) // Закрываем файл обработчика прерываний,
91 | close( _irq_ctrl_file ); // если он был открыт
92 |
93 | printf( "\n" ); // Переводим строку - чтобы приглашение вывелось в следующей строке
94 | echoOnOff( ECHO_ON ); // Переводим терминал в канонический режим работы
95 | exit( 0 );
96 | }
97 |
98 |
99 |
100 | /******************************************************************************
101 | * MAIN
102 | *
103 | * key = 0000260000
104 | * challenge1 = 0000000001
105 | * response1 = 5CA1BA
106 | * challenge2 = 0000000002
107 | * response2 = 07F2C0
108 | *------------------------
109 | * key = 7991F53219
110 | * challenge1 = 0000000001
111 | * response1 = CD6504
112 | * challenge2 = 0000000002
113 | * response2 = DF2F1D
114 | *
115 | *****************************************************************************/
116 |
117 | int main( int argc, char** argv )
118 | {
119 | bool irq_enable = false; // Признак наличия в системе драйвера обработчика прерываний IRQ0
120 | char buf[20];
121 |
122 | time_t time_start, time_now;
123 |
124 | uint64_t c1, r1, c2, r2, start_key;
125 | uint64_t key1 = -1;
126 | uint64_t key2 = -1;
127 | uint64_t kernels1 = 0;
128 | uint64_t kernels2 = 0;
129 | uint8_t data_set = 0; // Идентификатор текущего набора данных (0 или FF)
130 |
131 | // Флаги текущего состояния FPGA
132 |
133 | union
134 | {
135 | uint64_t Val;
136 |
137 | struct
138 | {
139 | uint8_t key_found;
140 | uint8_t key_not_found;
141 | uint32_t reserved1;
142 | uint8_t reserved2;
143 | };
144 | } flags;
145 |
146 | // Выключаем вывод нажатых клавиш в терминал
147 | echoOnOff( ECHO_OFF );
148 |
149 | // Устанавливаем свой обработчик нажатий Ctrl+C
150 | signal( SIGINT, exitToLinux );
151 |
152 | printf( "\n\nWARNING: Don't forget to load FPGA\n\nPress Ctrl+C for exit\n" );
153 |
154 | //------------------------------------------------------------//
155 | // Запрос входных данных
156 |
157 | while( 1 )
158 | {
159 | c1 = 0;
160 | r1 = 0;
161 | c2 = 0;
162 | r2 = 0;
163 | start_key = 0;
164 |
165 | printf( "\nType in first Challenge (40-bit HEX-number): " );
166 | fflush( stdout );
167 | if( getString( buf, sizeof(buf), "0123456789ABCDEF", true ) )
168 | sscanf( buf, "%llX", &c1 );
169 |
170 | printf( "\nType in first Response (24-bit HEX-number): " );
171 | fflush( stdout );
172 | if( getString( buf, sizeof(buf), "0123456789ABCDEF", true ) )
173 | sscanf( buf, "%llX", &r1 );
174 |
175 | printf( "\nType in second Challenge (40-bit HEX-number): " );
176 | fflush( stdout );
177 | if( getString( buf, sizeof(buf), "0123456789ABCDEF", true ) )
178 | sscanf( buf, "%llX", &c2 );
179 |
180 | printf( "\nType in second Response (24-bit HEX-number): " );
181 | fflush( stdout );
182 | if( getString( buf, sizeof(buf), "0123456789ABCDEF", true ) )
183 | sscanf( buf, "%llX", &r2 );
184 |
185 | printf( "\nType in Start Key (40-bit HEX-number): " );
186 | fflush( stdout );
187 | if( getString( buf, sizeof(buf), "0123456789ABCDEF", true ) )
188 | sscanf( buf, "%llX", &start_key );
189 |
190 | // Выводим результат ввода
191 | printf( "\n\nChallenge1 = %010llX", c1 );
192 | printf( "\nResponse1 = %06llX", r1 );
193 | printf( "\nChallenge2 = %010llX", c2 );
194 | printf( "\nResponse2 = %06llX", r2 );
195 | printf( "\nStart key = %010llX", start_key );
196 | printf( "\n\nContinue? (Y/N) " );
197 | fflush( stdout );
198 |
199 | // Ждём нажатия Y или N - выходим из цикла, если нажали 'Y'
200 | if( getYN() == 'Y' )
201 | break;
202 |
203 | // Выводим "N" в терминал
204 | printf( "N\n\n" );
205 | }
206 |
207 | // Выводим "Y" в терминал
208 | printf( "Y\n\n" );
209 |
210 | //------------------------------------------------------------//
211 | // Поиск ключа //
212 |
213 | // Открываем файл драйвера IRQ
214 |
215 | if( ( _irq_ctrl_file = open( "/dev/irq-ctrl", O_RDONLY ) ) == -1 )
216 | printf( "\nWARNING: IRQ-CTRL driver not found: Cyclic poll flags will be used\n" );
217 | else
218 | irq_enable = true;
219 |
220 | // Маппим регистры модуля DST40 в память
221 |
222 | if( ( _dst40_regs_file = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 )
223 | {
224 | perror( "\nERROR: could not open \"/dev/mem\"\n" );
225 | exitToLinux( SIGINT );
226 | }
227 |
228 | _h2f_base = mmap( NULL, 1024, ( PROT_READ | PROT_WRITE ), MAP_SHARED, _dst40_regs_file, 0xC0000000 );
229 |
230 | if( _h2f_base == MAP_FAILED )
231 | {
232 | _h2f_base = 0;
233 | perror( "\nERROR: mmap() failed\n" );
234 | exitToLinux( SIGINT );
235 | }
236 |
237 | printf( "\n\nKey search has been started\n\n" );
238 |
239 | // Запоминаем время старта поиска
240 | time_start = time( NULL );
241 |
242 | // Начинаем поиск со стартового ключа
243 | key1 = start_key;
244 |
245 | // Останавливаем FPGA
246 | alt_write_dword( DST40_RUN, 0 );
247 |
248 | while( 1 )
249 | {
250 | uint64_t curr_key;
251 |
252 | // Загружаем исходные данные в FPGA
253 | if( !data_set )
254 | {
255 | alt_write_dword( DST40_CHALLENGE, c1 );
256 | alt_write_dword( DST40_RESPONSE, r1 );
257 | alt_write_dword( DST40_START_KEY, key1 );
258 | curr_key = key1;
259 | }
260 | else
261 | {
262 | alt_write_dword( DST40_CHALLENGE, c2 );
263 | alt_write_dword( DST40_RESPONSE, r2 );
264 | alt_write_dword( DST40_START_KEY, key2 );
265 | curr_key = key2;
266 | }
267 |
268 | // Разрешаем FPGA искать ключ
269 | alt_write_dword( DST40_RUN, 1 );
270 |
271 | // Выводим информацию о текущем ключе, времени и прогрессе в терминал
272 | time_now = time( NULL ) - time_start;
273 | printf( "\rCurrent KEY: %010llX [%lds] [%lld%%] ", curr_key, time_now, ((curr_key * 100) / 0x4000000000) );
274 | fflush( stdout );
275 |
276 | if( irq_enable )
277 | {
278 | // Засыпаем до момента прерывания
279 | read( _irq_ctrl_file, buf, 1 );
280 |
281 | // Считываем флаги из FPGA
282 | flags.Val = alt_read_dword( DST40_FLAGS );
283 | }
284 | else
285 | {
286 | // Читаем флаги в цикле, пока какой-нибудь флаг не взведётся -
287 | // это приводит к полной загрузке одного ядра процессора.
288 | do
289 | {
290 | flags.Val = alt_read_dword( DST40_FLAGS );
291 | }
292 | while( !flags.Val );
293 | }
294 |
295 | // Считываем текущий ключ и биты ядер из FPGA
296 | if( !data_set )
297 | {
298 | key2 = alt_read_dword( DST40_KEY );
299 | kernels2 = alt_read_dword( DST40_KERNELS );
300 | }
301 | else
302 | {
303 | key1 = alt_read_dword( DST40_KEY );
304 | kernels1 = alt_read_dword( DST40_KERNELS );
305 | }
306 |
307 | // Останавливаем FPGA
308 | alt_write_dword( DST40_RUN, 0 );
309 |
310 | // Выходим из цикла, если все ключи перебраны
311 | if( flags.key_not_found )
312 | {
313 | time_now = time( NULL ) - time_start;
314 | printf( "\rCurrent KEY: 3FFFFFFFFF [%lds] [100%%] ", time_now );
315 | printf( "\n\nKey not found\n\n" );
316 | exitToLinux( SIGINT );
317 | }
318 |
319 | // Если уже выполнены две проверки одного и того-же ключа
320 | // с разными парами запрос/ответ и оба раза ключ обнаружен
321 | // одним и тем-же ядром, то считаем ключ найденным и выходим.
322 | if( key1 == key2 && ( kernels1 & kernels2 ) != 0 )
323 | {
324 | uint64_t full_key;
325 |
326 | switch( kernels1 & kernels2 )
327 | {
328 | case 2: full_key = 1; break;
329 | case 4: full_key = 2; break;
330 | case 8: full_key = 3; break;
331 | default: full_key = 0; break;
332 | }
333 |
334 | full_key = ( full_key << 38) | key1;
335 |
336 | printf( "\n\nKEY FOUND: %010llX\n\n", full_key );
337 | exitToLinux( SIGINT );
338 | }
339 |
340 | // Переключаемся на другой набор исходных данных
341 | data_set ^= 0xFF;
342 | }
343 |
344 | // Осчастливливаем Eclipse
345 | return 0;
346 | }
347 |
--------------------------------------------------------------------------------
/software/dst40/keyboard.c:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *
3 | * Набор методов для работы с клавиатурой.
4 | *
5 | *----------------------------------------------------------------------------
6 | * ESC-последовательности от дополнительных клавиш:
7 | *
8 | * HOME: 0x1B 0x5B 0x31 0x7E
9 | * INSERT: 0x1B 0x5B 0x32 0x7E
10 | * DELETE: 0x1B 0x5B 0x33 0x7E
11 | * END: 0x1B 0x5B 0x34 0x7E
12 | * PAGEUP: 0x1B 0x5B 0x35 0x7E
13 | * PAGEDN: 0x1B 0x5B 0x36 0x7E
14 | *
15 | * UP: 0x1B 0x5B 0x41
16 | * DOWN: 0x1B 0x5B 0x42
17 | * RIGHT: 0x1B 0x5B 0x43
18 | * LEFT: 0x1B 0x5B 0x44
19 | *
20 | * F1: 0x1B 0x5B 0x5B 0x41
21 | * F2: 0x1B 0x5B 0x5B 0x42
22 | * F3: 0x1B 0x5B 0x5B 0x43
23 | * F4: 0x1B 0x5B 0x5B 0x44
24 | * F5: 0x1B 0x5B 0x5B 0x45
25 | * F6: 0x1B 0x5B 0x31 0x37
26 | * F7: 0x1B 0x5B 0x31 0x38
27 | * F8: 0x1B 0x5B 0x31 0x39
28 | * F9: 0x1B 0x5B 0x32 0x30
29 | * F10: 0x1B 0x5B 0x32 0x31
30 | * F11: 0x1B 0x5B 0x32 0x33
31 | * F12: 0x1B 0x5B 0x32 0x34
32 | *****************************************************************************/
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include "keyboard.h"
48 |
49 |
50 | /******************************************************************************
51 | * Перевод терминала в режим ввода без буферирования и без эха или
52 | * возврат терминала в стандартный режим работы.
53 | *
54 | * Вход: mode = true - выключить буферизацию и эхо,
55 | * false - вернуть стандартный режим работы.
56 | *****************************************************************************/
57 |
58 | void echoOnOff( bool mode )
59 | {
60 | static bool cur_state = false;
61 | static struct termios oldattr;
62 |
63 | if( mode )
64 | {
65 | struct termios newattr;
66 |
67 | if( cur_state )
68 | return;
69 |
70 | tcgetattr( STDIN_FILENO, &oldattr ); // Запрашиваем текущие аттрибуты терминала и сохраняем их в oldattr
71 | newattr = oldattr; //
72 | newattr.c_lflag &= ~( ICANON | ECHO ); // Выключаем в атрибутах буферизацию и эхо
73 | newattr.c_cc[VTIME] = 0;
74 | newattr.c_cc[VMIN] = 1;
75 | tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); // и записываем изменённые атрибуты обратно в терминал
76 | cur_state = true; // Запоминаем, что режим работы терминала изменён.
77 | }
78 | else
79 | {
80 | if( !cur_state )
81 | return;
82 |
83 | tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); // Восстанавливаем прежний режим работы терминала.
84 | }
85 | }
86 |
87 |
88 | /******************************************************************************
89 | * Проверка нажатости клавиши.
90 | *
91 | * Чтобы в окне терминала не выводились нажатые клавиши нужно
92 | * перед вызовом этой функции вызвать echoOnOff(ECHO_OFF),
93 | * а после - echoOnOff(ECHO_ON).
94 | *
95 | * Выход: int - количество нажатых клавиш в очереди.
96 | *****************************************************************************/
97 |
98 | int kbhit( void )
99 | {
100 | int bytesWaiting;
101 |
102 | ioctl( STDIN_FILENO, FIONREAD, &bytesWaiting );
103 | return bytesWaiting;
104 | }
105 |
106 |
107 | /******************************************************************************
108 | * Ожидание нажатия клавиши - без вывода эха.
109 | *
110 | * Выход: int - код нажатой клавиши.
111 | *****************************************************************************/
112 |
113 | int getch( void )
114 | {
115 | struct termios oldattr, newattr;
116 | int ch;
117 |
118 | tcgetattr( STDIN_FILENO, &oldattr );
119 | newattr = oldattr;
120 | newattr.c_lflag &= ~( ICANON | ECHO );
121 | tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
122 | ch = getchar();
123 | tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
124 | return ch;
125 | }
126 |
127 |
128 | /******************************************************************************
129 | * Ожидание нажатия клавиши - в том числе функциональной.
130 | *
131 | * Выход: uint64_t - код нажатой клавиши
132 | *
133 | * Коды функциональных клавиш (для терминала Linux):
134 | *
135 | * KEY_UP 0x00000000001B5B41
136 | * KEY_DOWN 0x00000000001B5B42
137 | * KEY_RIGHT 0x00000000001B5B43
138 | * KEY_LEFT 0x00000000001B5B44
139 | * KEY_HOME 0x000000001B5B317E
140 | * KEY_INSERT 0x000000001B5B327E
141 | * KEY_DELETE 0x000000001B5B337E
142 | * KEY_END 0x000000001B5B347E
143 | * KEY_PAGEUP 0x000000001B5B357E
144 | * KEY_PAGEDN 0x000000001B5B367E
145 | * KEY_F1 0x000000001B5B5B41
146 | * KEY_F2 0x000000001B5B5B42
147 | * KEY_F3 0x000000001B5B5B43
148 | * KEY_F4 0x000000001B5B5B44
149 | * KEY_F5 0x000000001B5B5B45
150 | * KEY_F6 0x0000001B5B31377E
151 | * KEY_F7 0x0000001B5B31387E
152 | * KEY_F8 0x0000001B5B31397E
153 | * KEY_F9 0x0000001B5B32307E
154 | * KEY_F10 0x0000001B5B32317E
155 | * KEY_F11 0x0000001B5B32337E
156 | * KEY_F12 0x0000001B5B32347E
157 | *
158 | *****************************************************************************/
159 |
160 | uint64_t getKeyCode( void )
161 | {
162 | // Время ожидания остатка ESC-последовательности (в миллисекундах)
163 | #define WAIT_ESC_SEQ 100
164 |
165 | // Таблица, по которой будет выполняться поиск совпадения
166 | static const uint64_t funcKeyTable[] =
167 | {
168 | KEY_UP,
169 | KEY_DOWN,
170 | KEY_RIGHT,
171 | KEY_LEFT,
172 | KEY_HOME,
173 | KEY_INSERT,
174 | KEY_DELETE,
175 | KEY_END,
176 | KEY_PAGEUP,
177 | KEY_PAGEDN,
178 | KEY_F1,
179 | KEY_F2,
180 | KEY_F3,
181 | KEY_F4,
182 | KEY_F5,
183 | KEY_F6,
184 | KEY_F7,
185 | KEY_F8,
186 | KEY_F9,
187 | KEY_F10,
188 | KEY_F11,
189 | KEY_F12,
190 | 0
191 | };
192 |
193 | struct timespec ts = { 0, 1000000 }; // Время сна - 1000000ns = 1мс
194 | static uint8_t keyQueue[256]; // Кольцевой буфер для считанных кодов клавиш
195 | static uint8_t idxIn = 0; // Индекс записываемых в очередь символов
196 | static uint8_t idxOut = 0; // Индекс считываемых из очереди символов
197 | uint64_t keyCode = 0x1B5B;
198 | uint8_t escLen = 2;
199 | uint8_t lenQueue;
200 | uint8_t escTime = 0; // Счётчик миллисекунд, прошедших с момента получения ESC
201 | int len;
202 |
203 | while( 1 )
204 | {
205 | ioctl( STDIN_FILENO, FIONREAD, &len ); // Проверяем наличие непрочитанных из терминала данных
206 |
207 | for( ; len > 0 && (uint8_t)(idxIn+1) != idxOut; idxIn++, len-- ) // Если есть непрочитанные данные, то считываем их в кольцевой буфер
208 | read( STDIN_FILENO, keyQueue + idxIn, 1 ); // keyQueue - пока они не кончатся или пока не кончится место в буфере
209 |
210 | lenQueue = idxIn - idxOut; // Вычисляем кол-во данных в кольцевом буфере
211 |
212 | if( !lenQueue ) // Если кольцевой буфер пуст, то
213 | { //
214 | nanosleep( &ts, NULL ); // спим 1мс
215 | continue; // и продолжаем ждать следующие данные
216 | }
217 |
218 | if( keyQueue[idxOut] != 0x1B ) // Если текущий символ в кольцевом буфере не ESC, то выходим и
219 | return keyQueue[idxOut++]; // возвращаем этот символ, предварительно удалив его из кольцевого буфера.
220 |
221 | if( ++escTime == WAIT_ESC_SEQ ) // Инкрементируем счётчик времени: если прошло WAIT_ESC_SEQ мс с момента получения ESC,
222 | return keyQueue[idxOut++]; // то выходим и возвращаем ESC, предварительно удалив его из кольцевого буфера.
223 |
224 | if( lenQueue == 1 ) // Если в кольцевом буфере только один байт ESC, то
225 | { //
226 | nanosleep( &ts, NULL ); // спим 1мс
227 | continue; // и продолжаем ждать следующие данные
228 | }
229 |
230 | if( keyQueue[(uint8_t)(idxOut+1)] != 0x5B ) // Если следующий за ESC символ - не 0x5B, то выходим и
231 | return keyQueue[idxOut++]; // возвращаем ESC, предварительно удалив ESC из кольцевого буфера.
232 |
233 | while( lenQueue > escLen ) // При получении каждого следующего байта
234 | { //
235 | uint8_t i = 0; //
236 | //
237 | keyCode = ( keyCode << 8 ) | //
238 | keyQueue[(uint8_t)(idxOut + escLen)]; // дописываем принятый байт в хвост keyCode,
239 | escLen++; // инкрементируем счётчик принятых байт ESC-последовательности,
240 | //
241 | while( funcKeyTable[i] ) // и ищем новый ESC-код в списке функциональных клавиш:
242 | { //
243 | if( funcKeyTable[i++] == keyCode ) // если код нашёлся в списке, то
244 | { //
245 | idxOut += escLen; // удаляем его из циклического буфера,
246 | return keyCode; // выходим и возвращаем принятый код.
247 | }
248 | }
249 |
250 | if( escLen > 5 ) // Если принято уже больше 5 байт, а совпадения так и нет, то
251 | return keyQueue[idxOut++]; // прерываем приём ESC-последовательности:
252 | } // возвращаем ESC, предварительно удалив ESC из кольцевого буфера.
253 |
254 | nanosleep( &ts, NULL ); // спим 1мс
255 | }
256 |
257 | return 0; // Осчастливливаем Eclipse
258 |
259 | #undef WAIT_ESC_SEQ
260 | }
261 |
262 |
263 | /******************************************************************************
264 | * Ввод строки - с выводом эха.
265 | *
266 | * uint32_t getString( char *buf, uint32_t size, const char *mask )
267 | *
268 | * Вход: buf - указатель на входной буфер,
269 | * size - длина входного буфера,
270 | * mask - строка, содержащая все допустимые символы,
271 | * toup - true, если необходимо преобразовывать вводимые символы
272 | * в верхний регистр.
273 | *
274 | * Выход: int - длина введённой строки,
275 | * buf - введённая строка.
276 | *****************************************************************************/
277 |
278 | int32_t getString( char *buf, int32_t size, const char *mask, bool toup )
279 | {
280 | int32_t i;
281 | int32_t len = 0;
282 | int32_t pos = 0;
283 | int32_t len_prev, pos_prev;
284 |
285 | while( 1 )
286 | {
287 | uint64_t keyCode = getKeyCode(); // Ждём нажатия клавиши
288 |
289 | len_prev = len; // Запоминаем текущую длину строки
290 | pos_prev = pos; // Запоминаем текущую позицию
291 |
292 | switch( keyCode )
293 | {
294 | // ENTER - завершение ввода строки
295 | case KEY_ENTER:
296 | {
297 | buf[len] = 0;
298 | return len;
299 | }
300 |
301 | // Перемещение курсора в начало строки
302 | case KEY_HOME:
303 | {
304 | pos = 0;
305 | break;
306 | }
307 |
308 | // Перемещение курсора в конец строки
309 | case KEY_END:
310 | {
311 | pos = len;
312 | break;
313 | }
314 |
315 | // Перемещение курсора на одну позицию влево
316 | case KEY_LEFT:
317 | {
318 | if( pos > 0 )
319 | pos--;
320 |
321 | break;
322 | }
323 |
324 | // Перемещение курсора на одну позицию вправо
325 | case KEY_RIGHT:
326 | {
327 | if( pos < len )
328 | pos++;
329 |
330 | break;
331 | }
332 |
333 | // Удаление символа в текущей позиции
334 | case KEY_DELETE:
335 | {
336 | if( !len ) // Если строка пустая, то
337 | continue; // ничего не делаем
338 |
339 | for( i=pos+1; i < len; i++ ) // Удаляем символ в текущей позиции
340 | buf[i-1] = buf[i];
341 |
342 | len--; // Укорачиваем строку на один символ
343 | break;
344 | }
345 |
346 | // BACKSPACE - удаление предыдущего символа
347 | case KEY_BACKSPACE:
348 | {
349 | if( !pos ) // Если курсор стоит в самом начале строки, то
350 | continue; // ничего не делаем.
351 |
352 | for( i=pos; i < len; i++ ) // Удаляем предыдущий символ
353 | buf[i-1] = buf[i];
354 |
355 | pos--; // Переводим курсор на одну позицию левее
356 | len--; // Укорачиваем строку на один символ
357 | break;
358 | }
359 |
360 | // Все остальные функциональные клавиши игнорируем
361 | case KEY_ESC:
362 | case KEY_UP:
363 | case KEY_DOWN:
364 | case KEY_INSERT:
365 | case KEY_PAGEUP:
366 | case KEY_PAGEDN:
367 | case KEY_F1:
368 | case KEY_F2:
369 | case KEY_F3:
370 | case KEY_F4:
371 | case KEY_F5:
372 | case KEY_F6:
373 | case KEY_F7:
374 | case KEY_F8:
375 | case KEY_F9:
376 | case KEY_F10:
377 | case KEY_F11:
378 | case KEY_F12: break;
379 |
380 | // Обрабатываем все остальные символы
381 | default:
382 | {
383 | if( ( keyCode & 0xFF ) == 0x1B ) // Игнорируем все остальные ESC-последовательности
384 | continue;
385 |
386 | if( toup )
387 | keyCode = toupper( keyCode );
388 |
389 | // Проверяем введённый символ на допустимость
390 | if( strchr( mask, keyCode ) == NULL )
391 | continue;
392 |
393 | if( len >= (size-1) ) // Проверяем наличие места во входном буфере:
394 | continue; // ничего не делаем, если буфер заполнен до упора.
395 |
396 | if( pos == len )
397 | { // Если курсор стоит в конце строки, то
398 | buf[pos++] = keyCode; // просто дописываем новый символ в конец строки
399 | len++; // и инкрементируем длину строки.
400 | break;
401 | }
402 | // Если же курсор стоит не в конце строки, то
403 | for( i=len; i > pos; i-- ) // освобождаем место в строке под новый символ,
404 | buf[i] = buf[i-1];
405 |
406 | buf[pos++] = keyCode; // вставляем новый символ в текущую позицию,
407 | len++; // инкрементируем длину строки.
408 | }
409 | }
410 |
411 | // Выводим изменённую строку
412 |
413 | for( i = pos_prev; i > 0; i-- ) // Передвигаем курсор в начало строки
414 | printf( "\x08" );
415 |
416 | for( ; i < len; i++ ) // Печатаем новую строку
417 | printf( "%c", buf[i] );
418 |
419 | for( ; i < len_prev; i++ ) // Стираем хвостик, если строка стала короче
420 | printf( " " );
421 |
422 | for( ; i > pos; i-- ) // Возвращаем курсор в текущую позицию
423 | printf( "\x08" );
424 |
425 | fflush( stdout );
426 | }
427 |
428 | return 0; // Осчастливливаем Eclipse
429 | }
430 |
431 |
432 | /******************************************************************************
433 | * Ожидание нажатия клавиши Y или N.
434 | *
435 | * Выход: int - код нажатой клавиши.
436 | *****************************************************************************/
437 |
438 | int getYN( void )
439 | {
440 | int ch;
441 |
442 | while( 1 )
443 | {
444 | ch = toupper( getKeyCode() );
445 |
446 | if( ch == 'Y' || ch == 'N' )
447 | break;
448 | }
449 |
450 | return ch;
451 | }
452 |
--------------------------------------------------------------------------------
/software/dst40/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H_
2 | #define KEYBOARD_H_
3 |
4 | #include
5 |
6 | void echoOnOff( bool );
7 | int kbhit( void );
8 | int getch( void );
9 | int getYN( void );
10 | int32_t getString( char *, int32_t, const char *, bool );
11 | uint64_t getKeyCode( void );
12 |
13 |
14 | // Модификаторы для метода echoOnOff
15 |
16 | #define ECHO_OFF true
17 | #define ECHO_ON false
18 |
19 |
20 | // Таблица кодов функциональных клавиш
21 |
22 | #define KEY_BACKSPACE 0x0000000000000008
23 | #define KEY_ENTER 0x000000000000000A
24 | #define KEY_ESC 0x000000000000001B
25 |
26 | #define KEY_UP 0x00000000001B5B41
27 | #define KEY_DOWN 0x00000000001B5B42
28 | #define KEY_RIGHT 0x00000000001B5B43
29 | #define KEY_LEFT 0x00000000001B5B44
30 |
31 | #define KEY_HOME 0x000000001B5B317E
32 | #define KEY_INSERT 0x000000001B5B327E
33 | #define KEY_DELETE 0x000000001B5B337E
34 | #define KEY_END 0x000000001B5B347E
35 | #define KEY_PAGEUP 0x000000001B5B357E
36 | #define KEY_PAGEDN 0x000000001B5B367E
37 |
38 | #define KEY_F1 0x000000001B5B5B41
39 | #define KEY_F2 0x000000001B5B5B42
40 | #define KEY_F3 0x000000001B5B5B43
41 | #define KEY_F4 0x000000001B5B5B44
42 | #define KEY_F5 0x000000001B5B5B45
43 |
44 | #define KEY_F6 0x0000001B5B31377E
45 | #define KEY_F7 0x0000001B5B31387E
46 | #define KEY_F8 0x0000001B5B31397E
47 |
48 | #define KEY_F9 0x0000001B5B32307E
49 | #define KEY_F10 0x0000001B5B32317E
50 | #define KEY_F11 0x0000001B5B32337E
51 | #define KEY_F12 0x0000001B5B32347E
52 |
53 |
54 | #endif /* KEYBOARD_H_ */
55 |
--------------------------------------------------------------------------------
/software/dst40test/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
83 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/software/dst40test/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | dst40test
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
25 |
26 |
27 |
--------------------------------------------------------------------------------
/software/dst40test/.settings/org.eclipse.cdt.codan.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.cdt.codan.checkers.errnoreturn=Warning
3 | org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
4 | org.eclipse.cdt.codan.checkers.errreturnvalue=Error
5 | org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
6 | org.eclipse.cdt.codan.checkers.noreturn=Error
7 | org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
8 | org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
9 | org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
10 | org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
11 | org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
12 | org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
13 | org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
14 | org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
15 | org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
16 | org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
17 | org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
18 | org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
19 | org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
20 | org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
21 | org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
22 | org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
23 | org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
24 | org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
25 | org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
26 | org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
27 | org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
28 | org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
29 | org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
30 | org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
31 | org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
32 | org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
33 | org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
34 | org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
35 | org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
36 | org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
37 | org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
38 | org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
39 | org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
40 | org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
41 | org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
42 | org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
43 | org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
44 | org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
45 | org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
46 | org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
47 | org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
48 | org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
49 | org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
50 | org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
51 | org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
52 | org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
53 | org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
54 | org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
55 | org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
56 | org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
57 | org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
58 | org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
59 | org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
60 | org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
61 | org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
62 | org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
63 | org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
64 | org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
65 | org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
66 | org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
67 | org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
68 |
--------------------------------------------------------------------------------
/software/dst40test/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=UTF-8
3 |
--------------------------------------------------------------------------------
/software/dst40test/dst40.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 |
4 | typedef union
5 | {
6 | uint64_t Val;
7 |
8 | struct
9 | {
10 | uint8_t b0:1;
11 | uint8_t b1:1;
12 | uint8_t b2:1;
13 | uint8_t b3:1;
14 | uint8_t b4:1;
15 | uint8_t b5:1;
16 | uint8_t b6:1;
17 | uint8_t b7:1;
18 | uint8_t b8:1;
19 | uint8_t b9:1;
20 | uint8_t b10:1;
21 | uint8_t b11:1;
22 | uint8_t b12:1;
23 | uint8_t b13:1;
24 | uint8_t b14:1;
25 | uint8_t b15:1;
26 | uint8_t b16:1;
27 | uint8_t b17:1;
28 | uint8_t b18:1;
29 | uint8_t b19:1;
30 | uint8_t b20:1;
31 | uint8_t b21:1;
32 | uint8_t b22:1;
33 | uint8_t b23:1;
34 | uint8_t b24:1;
35 | uint8_t b25:1;
36 | uint8_t b26:1;
37 | uint8_t b27:1;
38 | uint8_t b28:1;
39 | uint8_t b29:1;
40 | uint8_t b30:1;
41 | uint8_t b31:1;
42 | uint8_t b32:1;
43 | uint8_t b33:1;
44 | uint8_t b34:1;
45 | uint8_t b35:1;
46 | uint8_t b36:1;
47 | uint8_t b37:1;
48 | uint8_t b38:1;
49 | uint8_t b39:1;
50 | uint8_t reserved1;
51 | uint8_t reserved2;
52 | uint8_t reserved3;
53 | };
54 | } WORD40;
55 |
56 |
57 |
58 | /*
59 | * Расчёт новых двух старших бит хэша
60 | */
61 |
62 | uint64_t block192( uint64_t hash_in, uint64_t key_in )
63 | {
64 | uint8_t fa[32] = { 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1 };
65 | uint8_t fb[32] = { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 };
66 | uint8_t fc[32] = { 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1 };
67 | uint8_t fd[32] = { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0 };
68 | uint8_t fe[16] = { 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0 };
69 | uint8_t fg[16] = { 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0 };
70 | uint8_t fh[16] = { 0, 0, 2, 3, 3, 1, 2, 1, 1, 2, 1, 3, 3, 2, 0, 0 };
71 |
72 | WORD40 hash;
73 | WORD40 key;
74 |
75 | hash.Val = hash_in;
76 | key.Val = key_in;
77 |
78 | uint8_t fa1 = fa[ (key.b39 << 4) | (key.b31 << 3) | (hash.b39 << 2) | (hash.b31 << 1) | hash.b23 ];
79 | uint8_t fb2 = fb[ (key.b38 << 4) | (key.b30 << 3) | (hash.b38 << 2) | (hash.b30 << 1) | hash.b22 ];
80 | uint8_t fc3 = fc[ (key.b23 << 4) | (key.b15 << 3) | (key.b7 << 2) | (hash.b15 << 1) | hash.b7 ];
81 | uint8_t fd4 = fd[ (key.b22 << 4) | (key.b14 << 3) | (key.b6 << 2) | (hash.b14 << 1) | hash.b6 ];
82 |
83 | uint8_t fa5 = fa[ (key.b37 << 4) | (key.b29 << 3) | (hash.b37 << 2) | (hash.b29 << 1) | hash.b21 ];
84 | uint8_t fb6 = fb[ (key.b36 << 4) | (key.b28 << 3) | (hash.b36 << 2) | (hash.b28 << 1) | hash.b20 ];
85 | uint8_t fc7 = fc[ (key.b21 << 4) | (key.b13 << 3) | (key.b5 << 2) | (hash.b13 << 1) | hash.b5 ];
86 | uint8_t fd8 = fd[ (key.b20 << 4) | (key.b12 << 3) | (key.b4 << 2) | (hash.b12 << 1) | hash.b4 ];
87 |
88 | uint8_t fa9 = fa[ (key.b35 << 4) | (key.b27 << 3) | (hash.b35 << 2) | (hash.b27 << 1) | hash.b19 ];
89 | uint8_t fb10 = fb[ (key.b34 << 4) | (key.b26 << 3) | (hash.b34 << 2) | (hash.b26 << 1) | hash.b18 ];
90 | uint8_t fc11 = fc[ (key.b19 << 4) | (key.b11 << 3) | (key.b3 << 2) | (hash.b11 << 1) | hash.b3 ];
91 | uint8_t fd12 = fd[ (key.b18 << 4) | (key.b10 << 3) | (key.b2 << 2) | (hash.b10 << 1) | hash.b2 ];
92 |
93 | uint8_t fa13 = fa[ (key.b33 << 4) | (key.b25 << 3) | (hash.b33 << 2) | (hash.b25 << 1) | hash.b17 ];
94 | uint8_t fb14 = fb[ (key.b32 << 4) | (key.b24 << 3) | (hash.b32 << 2) | (hash.b24 << 1) | hash.b16 ];
95 | uint8_t fe15 = fe[ (key.b17 << 3) | (key.b9 << 2) | (key.b1 << 1) | hash.b9 ];
96 | uint8_t fe16 = fe[ (key.b16 << 3) | (key.b8 << 2) | (key.b0 << 1) | hash.b8 ];
97 |
98 | uint8_t fg1 = fg[ (fa1 << 3) | (fb2 << 2) | (fc3 << 1) | fd4 ];
99 | uint8_t fg2 = fg[ (fa5 << 3) | (fb6 << 2) | (fc7 << 1) | fd8 ];
100 | uint8_t fg3 = fg[ (fa9 << 3) | (fb10 << 2) | (fc11 << 1) | fd12 ];
101 | uint8_t fg4 = fg[ (fa13 << 3) | (fb14 << 2) | (fe15 << 1) | fe16 ];
102 |
103 | uint8_t fh1 = fh[ (fg1 << 3) | (fg2 << 2) | (fg3 << 1) | fg4 ];
104 |
105 | uint64_t res = fh1 ^ ( (hash.b1 << 1) | hash.b0 );
106 |
107 | return res;
108 | }
109 |
110 |
111 | /******************************************************************************
112 | * Функция хэширования 40-битного числа по алгоритму DST40.
113 | *****************************************************************************/
114 |
115 | uint64_t dst40hash( uint64_t challenge, uint64_t key )
116 | {
117 | uint8_t i;
118 | uint8_t cnt;
119 |
120 | uint64_t hash40 = challenge;
121 | uint64_t key40 = key;
122 |
123 | for( i=0, cnt=0; i < 192; i++ )
124 | {
125 | WORD40 tmp;
126 |
127 | hash40 = (block192( hash40, key40 ) << 38) | (hash40 >> 2);
128 |
129 | if( cnt == 1 )
130 | {
131 | tmp.Val = key40;
132 |
133 | key40 = ( (uint64_t)(tmp.b0 ^ tmp.b2 ^ tmp.b19 ^ tmp.b21) << 39 ) | (key40 >> 1);
134 | }
135 |
136 | if( ++cnt == 3 )
137 | cnt = 0;
138 | }
139 |
140 | return (hash40 >> 16);
141 | }
142 |
--------------------------------------------------------------------------------
/software/dst40test/dst40test.c:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *
3 | * Программа для тестирования работы модуля DST40.
4 | *
5 | * Программа заточена под четырёхъядерный вариант схемы FPGA.
6 | *
7 | * Алгоритм:
8 | *
9 | * 1. Генерация случайных challenge и key.
10 | * 2. Расчёт response.
11 | * 3. Загрузка challenge, response и key в модуль DST40.
12 | * 4. Старт DST40.
13 | * 5. Ожидание завершения работы модуля DST40.
14 | * 6. Если модуль не нашёл ключ - выводим сообщение об ошибке и переходим на 1.
15 | * 7. Если модуль нашёл ключ, то считываем его и сравниваем с нашим.
16 | * 8. Если ключи не совпали, то выводим сообщение об ошибке и переходим на 1.
17 | * 9. Выводим время, прошедшее с момента старта программы.
18 | * 10. Опрашиваем клавиатуру.
19 | * 11. Если нажали ESC, то выходим из программы.
20 | * 12. Переходим на 1.
21 | *
22 | *----------------------------------------------------------------------------
23 | *
24 | * Адресная карта модуля DST40 (четырёхядерный вариант):
25 | *
26 | * 0 - challenge ( 40 бит, Чтение/Запись ) Первый запрос
27 | * 1 - response ( 24 бита, Чтение/Запись ) Первый ответ
28 | * 2 - start_key ( 40 бит, Чтение/Запись ) Ключ, с которого начинать поиск
29 | * 3 - run ( 1 бит, Чтение/Запись ) Флаг запуска поиска
30 | * 4 - флаги:
31 | * бит 0 - key_found_w ( 1 бит, Только чтение ) Флаг "ключ найден"
32 | * бит 8 - key_not_found_w ( 1 бит, Только чтение ) Флаг "ключ не найден"
33 | * 5 - key ( 38 бит, Только чтение ) Найденный ключ (младшие биты)
34 | * 6 - kernels ( 4 бита, Только чтение ) Биты ядер, нашедших ключ
35 | *
36 | *****************************************************************************/
37 |
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include "hwlib.h"
46 | #include "socal/socal.h"
47 | #include "socal/hps.h"
48 | #include "socal/alt_gpio.h"
49 | #include
50 | #include
51 | #include
52 | #include
53 | #include
54 | #include
55 |
56 | uint64_t dst40hash( uint64_t, uint64_t );
57 |
58 | int kbhit( void );
59 | int getch( void );
60 |
61 |
62 |
63 | /******************************************************************************
64 | * Функция генерации случайного 40-битного числа
65 | *****************************************************************************/
66 |
67 | uint64_t getRand40( void )
68 | {
69 | uint64_t rnd40;
70 |
71 | rnd40 = ( (uint64_t)(rand() % 256) << 32 ) +
72 | ( (uint64_t)(rand() % 256) << 24 ) +
73 | ( (uint64_t)(rand() % 256) << 16 ) +
74 | ( (uint64_t)(rand() % 256) << 8 ) +
75 | ( (uint64_t)(rand() % 256) );
76 |
77 | return rnd40;
78 | }
79 |
80 |
81 |
82 | /******************************************************************************
83 | * Преобразование старших бит ключа в маску бита ядра.
84 | *
85 | * Вход: key - ключ,
86 | * Выход: Битовая маска ядра.
87 | *****************************************************************************/
88 |
89 | uint64_t getMaskKernel( uint64_t key )
90 | {
91 | uint64_t kernel = key >> 38;
92 | uint64_t mask = 1;
93 |
94 | for( ; kernel > 0; kernel-- )
95 | mask <<= 1;
96 |
97 | return mask;
98 | }
99 |
100 |
101 | int main( int argc, char** argv )
102 | {
103 | void* h2f_base;
104 | int fd;
105 |
106 | time_t time_start, time_now, time_prev;
107 |
108 | uint64_t challenge;
109 | uint64_t response;
110 | uint64_t key;
111 |
112 | uint64_t testCount = 0;
113 | uint64_t errCount = 0;
114 |
115 | // Флаги текущего состояния FPGA
116 |
117 | union
118 | {
119 | uint64_t Val;
120 |
121 | struct
122 | {
123 | uint8_t key_found;
124 | uint8_t key_not_found;
125 | uint32_t reserved1;
126 | uint8_t reserved2;
127 | };
128 | } flags;
129 |
130 | // Инициализируем генератор случайных чисел.
131 |
132 | srand( time(NULL) );
133 |
134 | // Маппим регистры модуля DST40 в память
135 |
136 | if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 )
137 | {
138 | perror( "\r\nERROR: could not open \"/dev/mem\"" );
139 | return( 1 );
140 | }
141 |
142 | h2f_base = mmap( NULL, 1024, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, 0xC0000000 );
143 |
144 | if( h2f_base == MAP_FAILED )
145 | {
146 | perror( "\r\nERROR: mmap() failed" );
147 | close( fd );
148 | return(1);
149 | }
150 |
151 | printf( "\r\nPress ESC for exit\r\n\r\n" );
152 | fflush( stdout );
153 |
154 | // Настраиваем счётчики времени
155 | time_start = time( NULL );
156 | time_prev = time_start;
157 |
158 | // Цикл тестирования работы FPGA
159 | while( 1 )
160 | {
161 | // Проверяем нажатие ESC на клавиатуре
162 | if( kbhit() && getch() == 27 )
163 | {
164 | printf( "\r\n\r\nKey ESC has been pressed.\r\n" );
165 | break;
166 | }
167 |
168 | // Генерим случайные запрос и ключ
169 | challenge = getRand40();
170 | key = getRand40();
171 |
172 | // Вычисляем ответ
173 | response = dst40hash( challenge, key );
174 |
175 | // Останавливаем FPGA
176 | alt_write_dword( h2f_base + 24, 0 );
177 |
178 | // Загружаем исходные данные в FPGA
179 | alt_write_dword( h2f_base + 0, challenge );
180 | alt_write_dword( h2f_base + 8, response );
181 | alt_write_dword( h2f_base + 16, key );
182 |
183 | // Разрешаем FPGA искать ключ
184 | alt_write_dword( h2f_base + 24, 1 );
185 |
186 | // Читаем флаги в цикле, пока какой-нибудь флаг не взведётся -
187 | // это приводит к полной загрузке одного ядра процессора.
188 | do
189 | {
190 | flags.Val = alt_read_dword( h2f_base + 32 );
191 | }
192 | while( !flags.Val );
193 |
194 | // Проверяем - нашёлся ли ключ
195 | if( flags.key_found )
196 | {
197 | // Считываем найденный ключ из FPGA
198 | uint64_t result = alt_read_dword( h2f_base + 40 );
199 |
200 | // Считываем биты ядер, нашедших ключ
201 | uint64_t kernels = alt_read_dword( h2f_base + 48 );
202 |
203 | // Вычисляем маску ядра, которое должно было найти ключ
204 | uint64_t mask = getMaskKernel( key );
205 |
206 | // Проверяем совпадение найденного ключа с исходным и совпадение номера ядра с требуемым
207 | if( result != (key & 0x3FFFFFFFFF) || (kernels & mask) == 0 )
208 | {
209 | printf( "\r\nError: Count=%lld, CHALLENGE=%010llX, RESPONSE=%06llX, KEY=%010llX, KEY_FPGA=%010llX, KERNELS=%lld\r\n", testCount, challenge, response, key, result, kernels );
210 | errCount++;
211 | }
212 | }
213 | else if( flags.key_not_found )
214 | {
215 | printf( "\r\nError: Key not found\r\n" );
216 |
217 | // Инкрементируем счётчик ошибок
218 | errCount++;
219 | }
220 | else
221 | {
222 | printf( "\r\nError: unknown interrupt\r\n" );
223 |
224 | // Инкрементируем счётчик ошибок
225 | errCount++;
226 | break;
227 | }
228 |
229 | testCount++;
230 |
231 | time_now = time( NULL ) - time_start;
232 |
233 | if( time_now != time_prev )
234 | {
235 | time_prev = time_now;
236 | printf( "\rTime: %ld | Tests: %lld | Errors: %lld", time_now, testCount, errCount );
237 | // wprintf( L"\rВремя: %ld. Выполнено проверок: %lld. Обнаружено ошибок: %lld", time_now, testCount, errCount );
238 | fflush( stdout );
239 | }
240 | }
241 |
242 | // Размапливаем регистры модуля DST40
243 |
244 | if( munmap( h2f_base, 1024 ) != 0 )
245 | {
246 | printf( "ERROR: munmap() failed...\n" );
247 | close( fd );
248 | return( 1 );
249 | }
250 |
251 | close( fd );
252 |
253 | return 0;
254 | }
255 |
--------------------------------------------------------------------------------
/software/dst40test/keyboard.c:
--------------------------------------------------------------------------------
1 | // #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 |
11 | /*
12 | * Проверка - нажата ли клавиша на клавиатуре
13 | */
14 | /*
15 | int kbhit( void )
16 | {
17 | struct timeval tv;
18 | fd_set read_fd;
19 |
20 | // Do not wait at all, not even a microsecond
21 | tv.tv_sec=0;
22 | tv.tv_usec=0;
23 |
24 | // Must be done first to initialize read_fd
25 | FD_ZERO( &read_fd );
26 |
27 | // Makes select() ask if input is ready: 0 is the file descriptor for stdin
28 | FD_SET( 0, &read_fd );
29 |
30 | // The first parameter is the number of the largest file descriptor to check + 1.
31 | if( select( 1, &read_fd, NULL, NULL, &tv) == -1 )
32 | return 0; // An error occured
33 |
34 | // read_fd now holds a bit map of files that are readable. We test the entry for the standard input (file 0).
35 | if( FD_ISSET(0,&read_fd) )
36 | // Character pending on stdin
37 | return 1;
38 |
39 | // no characters were pending
40 | return 0;
41 | }
42 | */
43 |
44 | int kbhit( void )
45 | {
46 | static const int STDIN = 0;
47 | static bool initialized = false;
48 |
49 | if (! initialized)
50 | {
51 | // Use termios to turn off line buffering
52 | struct termios term;
53 |
54 | tcgetattr( STDIN, &term );
55 | term.c_lflag &= ~ICANON;
56 | tcsetattr( STDIN, TCSANOW, &term );
57 | setbuf( stdin, NULL );
58 | initialized = true;
59 | }
60 |
61 | int bytesWaiting;
62 |
63 | ioctl( STDIN, FIONREAD, &bytesWaiting );
64 | return bytesWaiting;
65 | }
66 |
67 |
68 | /******************************************************************************
69 | * Ожидание нажатия клавиши - без вывода эха.
70 | *****************************************************************************/
71 |
72 | int getch( void )
73 | {
74 | struct termios oldattr, newattr;
75 | int ch;
76 |
77 | tcgetattr( STDIN_FILENO, &oldattr );
78 | newattr = oldattr;
79 | newattr.c_lflag &= ~( ICANON | ECHO );
80 | tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
81 | ch = getchar();
82 | tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
83 | return ch;
84 | }
85 |
--------------------------------------------------------------------------------
/source/Block64.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Один из 64 модулей для построения одного комбинаторного ядра DST40.
4 |
5 | ******************************************************************************/
6 |
7 | module Block64
8 | (
9 | input clock_i, // Такты
10 | input run_i, // Разрешение работы
11 | input [39:0] hash_i, // Входной хэш (такт 0)
12 | input [39:0] key_i, // Входной ключ (такт 0)
13 | output [39:0] hash_o, // Выходной хэш (такт 3)
14 | output [39:0] key_o // Выходной ключ (такт 3)
15 | );
16 |
17 |
18 | //==============================================================//
19 | // Внутренние провода/регистры
20 | //==============================================================//
21 |
22 | wire [3:0] hi1_w; // Входная шина H на такте 1
23 | wire [1:0] ho1_w; // Выходная шина H на такте 1
24 |
25 | wire [3:0] hi2_w; // Входная шина H на такте 2
26 | wire [1:0] ho2_w; // Выходная шина H на такте 2
27 |
28 | wire [3:0] hi3_w; // Входная шина H на такте 3
29 | wire [1:0] ho3_w; // Выходная шина H на такте 3
30 |
31 | wire [3:0] g1i1_w; // Входная шина G1 на такте 1
32 | wire [3:0] g2i1_w; // Входная шина G2 на такте 1
33 | wire [3:0] g3i1_w; // Входная шина G3 на такте 1
34 | wire [3:0] g4i1_w; // Входная шина G4 на такте 1
35 |
36 | wire [3:0] g1i2_w; // Входная шина G1 на такте 2
37 | wire [3:0] g2i2_w; // Входная шина G2 на такте 2
38 | wire [3:0] g3i2_w; // Входная шина G3 на такте 2
39 | wire [3:0] g4i2_w; // Входная шина G4 на такте 2
40 |
41 | wire [3:0] g1i3_w; // Входная шина G1 на такте 3
42 | wire [3:0] g2i3_w; // Входная шина G2 на такте 3
43 | wire [3:0] g3i3_w; // Входная шина G3 на такте 3
44 | wire [3:0] g4i3_w; // Входная шина G4 на такте 3
45 |
46 | wire [39:0] hash1_w; // HASH после такта 1
47 | wire [39:0] key1_w; // KEY после такта 1
48 | wire [39:0] hash2_w; // HASH после такта 2
49 | wire [39:0] key2_w; // KEY после такта 2
50 | wire [39:0] hash3_w; // HASH после такта 3
51 | wire [39:0] key3_w; // KEY после такта 3
52 |
53 | reg [39:0] hash_out_reg;
54 | reg [39:0] key_out_reg;
55 |
56 |
57 |
58 |
59 | //==============================================================//
60 | // Комбинаторная схемотехника
61 | //==============================================================//
62 |
63 | assign hash_o = hash_out_reg;
64 | assign key_o = key_out_reg;
65 |
66 |
67 | //--------------------------------------------------------------//
68 | // Такт 1 //
69 |
70 | Fh H1_INST
71 | (
72 | .in ( hi1_w ),
73 | .out ( ho1_w )
74 | );
75 |
76 | Fg G11_INST
77 | (
78 | .in ( g1i1_w ),
79 | .out ( hi1_w[3] )
80 | );
81 |
82 | Fg G21_INST
83 | (
84 | .in ( g2i1_w ),
85 | .out ( hi1_w[2] )
86 | );
87 |
88 | Fg G31_INST
89 | (
90 | .in ( g3i1_w ),
91 | .out ( hi1_w[1] )
92 | );
93 |
94 | Fg G41_INST
95 | (
96 | .in ( g4i1_w ),
97 | .out ( hi1_w[0] )
98 | );
99 |
100 | Fa F11_INST
101 | (
102 | .in ( { key_i[39], key_i[31], hash_i[39], hash_i[31], hash_i[23] } ),
103 | .out ( g1i1_w[3] )
104 | );
105 |
106 | Fb F21_INST
107 | (
108 | .in ( { key_i[38], key_i[30], hash_i[38], hash_i[30], hash_i[22] } ),
109 | .out ( g1i1_w[2] )
110 | );
111 |
112 | Fa F51_INST
113 | (
114 | .in ( { key_i[37], key_i[29], hash_i[37], hash_i[29], hash_i[21] } ),
115 | .out ( g2i1_w[3] )
116 | );
117 |
118 | Fb F61_INST
119 | (
120 | .in ( { key_i[36], key_i[28], hash_i[36], hash_i[28], hash_i[20] } ),
121 | .out ( g2i1_w[2] )
122 | );
123 |
124 | Fa F91_INST
125 | (
126 | .in ( { key_i[35], key_i[27], hash_i[35], hash_i[27], hash_i[19] } ),
127 | .out ( g3i1_w[3] )
128 | );
129 |
130 | Fb F101_INST
131 | (
132 | .in ( { key_i[34], key_i[26], hash_i[34], hash_i[26], hash_i[18] } ),
133 | .out ( g3i1_w[2] )
134 | );
135 |
136 | Fa F131_INST
137 | (
138 | .in ( { key_i[33], key_i[25], hash_i[33], hash_i[25], hash_i[17] } ),
139 | .out ( g4i1_w[3] )
140 | );
141 |
142 | Fb F141_INST
143 | (
144 | .in ( { key_i[32], key_i[24], hash_i[32], hash_i[24], hash_i[16] } ),
145 | .out ( g4i1_w[2] )
146 | );
147 |
148 | Fc F31_INST
149 | (
150 | .in ( { key_i[23], key_i[15], key_i[7], hash_i[15], hash_i[7] } ),
151 | .out ( g1i1_w[1] )
152 | );
153 |
154 | Fd F41_INST
155 | (
156 | .in ( { key_i[22], key_i[14], key_i[6], hash_i[14], hash_i[6] } ),
157 | .out ( g1i1_w[0] )
158 | );
159 |
160 | Fc F71_INST
161 | (
162 | .in ( { key_i[21], key_i[13], key_i[5], hash_i[13], hash_i[5] } ),
163 | .out ( g2i1_w[1] )
164 | );
165 |
166 | Fd F81_INST
167 | (
168 | .in ( { key_i[20], key_i[12], key_i[4], hash_i[12], hash_i[4] } ),
169 | .out ( g2i1_w[0] )
170 | );
171 |
172 | Fc F111_INST
173 | (
174 | .in ( { key_i[19], key_i[11], key_i[3], hash_i[11], hash_i[3] } ),
175 | .out ( g3i1_w[1] )
176 | );
177 |
178 | Fd F121_INST
179 | (
180 | .in ( { key_i[18], key_i[10], key_i[2], hash_i[10], hash_i[2] } ),
181 | .out ( g3i1_w[0] )
182 | );
183 |
184 | Fe F151_INST
185 | (
186 | .in ( { key_i[17], key_i[9], key_i[1], hash_i[9] } ),
187 | .out ( g4i1_w[1] )
188 | );
189 |
190 | Fe F161_INST
191 | (
192 | .in ( { key_i[16], key_i[8], key_i[0], hash_i[8] } ),
193 | .out ( g4i1_w[0] )
194 | );
195 |
196 |
197 | //--------------------------------------------------------------//
198 | // Результат такта 1 / Исходные данные для такта 2 //
199 |
200 | assign hash1_w = { ho1_w ^ hash_i[1:0], hash_i[39:2] };
201 | assign key1_w = key_i;
202 |
203 |
204 | //--------------------------------------------------------------//
205 | // Такт 2 //
206 |
207 | Fh H2_INST
208 | (
209 | .in ( hi2_w ),
210 | .out ( ho2_w )
211 | );
212 |
213 | Fg G12_INST
214 | (
215 | .in ( g1i2_w ),
216 | .out ( hi2_w[3] )
217 | );
218 |
219 | Fg G22_INST
220 | (
221 | .in ( g2i2_w ),
222 | .out ( hi2_w[2] )
223 | );
224 |
225 | Fg G32_INST
226 | (
227 | .in ( g3i2_w ),
228 | .out ( hi2_w[1] )
229 | );
230 |
231 | Fg G42_INST
232 | (
233 | .in ( g4i2_w ),
234 | .out ( hi2_w[0] )
235 | );
236 |
237 | Fa F12_INST
238 | (
239 | .in ( { key1_w[39], key1_w[31], hash1_w[39], hash1_w[31], hash1_w[23] } ),
240 | .out ( g1i2_w[3] )
241 | );
242 |
243 | Fb F22_INST
244 | (
245 | .in ( { key1_w[38], key1_w[30], hash1_w[38], hash1_w[30], hash1_w[22] } ),
246 | .out ( g1i2_w[2] )
247 | );
248 |
249 | Fa F52_INST
250 | (
251 | .in ( { key1_w[37], key1_w[29], hash1_w[37], hash1_w[29], hash1_w[21] } ),
252 | .out ( g2i2_w[3] )
253 | );
254 |
255 | Fb F62_INST
256 | (
257 | .in ( { key1_w[36], key1_w[28], hash1_w[36], hash1_w[28], hash1_w[20] } ),
258 | .out ( g2i2_w[2] )
259 | );
260 |
261 | Fa F92_INST
262 | (
263 | .in ( { key1_w[35], key1_w[27], hash1_w[35], hash1_w[27], hash1_w[19] } ),
264 | .out ( g3i2_w[3] )
265 | );
266 |
267 | Fb F102_INST
268 | (
269 | .in ( { key1_w[34], key1_w[26], hash1_w[34], hash1_w[26], hash1_w[18] } ),
270 | .out ( g3i2_w[2] )
271 | );
272 |
273 | Fa F132_INST
274 | (
275 | .in ( { key1_w[33], key1_w[25], hash1_w[33], hash1_w[25], hash1_w[17] } ),
276 | .out ( g4i2_w[3] )
277 | );
278 |
279 | Fb F142_INST
280 | (
281 | .in ( { key1_w[32], key1_w[24], hash1_w[32], hash1_w[24], hash1_w[16] } ),
282 | .out ( g4i2_w[2] )
283 | );
284 |
285 | Fc F32_INST
286 | (
287 | .in ( { key1_w[23], key1_w[15], key1_w[7], hash1_w[15], hash1_w[7] } ),
288 | .out ( g1i2_w[1] )
289 | );
290 |
291 | Fd F42_INST
292 | (
293 | .in ( { key1_w[22], key1_w[14], key1_w[6], hash1_w[14], hash1_w[6] } ),
294 | .out ( g1i2_w[0] )
295 | );
296 |
297 | Fc F72_INST
298 | (
299 | .in ( { key1_w[21], key1_w[13], key1_w[5], hash1_w[13], hash1_w[5] } ),
300 | .out ( g2i2_w[1] )
301 | );
302 |
303 | Fd F82_INST
304 | (
305 | .in ( { key1_w[20], key1_w[12], key1_w[4], hash1_w[12], hash1_w[4] } ),
306 | .out ( g2i2_w[0] )
307 | );
308 |
309 | Fc F112_INST
310 | (
311 | .in ( { key1_w[19], key1_w[11], key1_w[3], hash1_w[11], hash1_w[3] } ),
312 | .out ( g3i2_w[1] )
313 | );
314 |
315 | Fd F122_INST
316 | (
317 | .in ( { key1_w[18], key1_w[10], key1_w[2], hash1_w[10], hash1_w[2] } ),
318 | .out ( g3i2_w[0] )
319 | );
320 |
321 | Fe F152_INST
322 | (
323 | .in ( { key1_w[17], key1_w[9], key1_w[1], hash1_w[9] } ),
324 | .out ( g4i2_w[1] )
325 | );
326 |
327 | Fe F162_INST
328 | (
329 | .in ( { key1_w[16], key1_w[8], key1_w[0], hash1_w[8] } ),
330 | .out ( g4i2_w[0] )
331 | );
332 |
333 |
334 | //--------------------------------------------------------------//
335 | // Результат такта 2 / Исходные данные для такта 3 //
336 |
337 | assign hash2_w = { ho2_w ^ hash1_w[1:0], hash1_w[39:2] };
338 | assign key2_w = { key1_w[0] ^ key1_w[2] ^ key1_w[19] ^ key1_w[21], key1_w[39:1] };
339 |
340 |
341 | //--------------------------------------------------------------//
342 | // Такт 3 //
343 |
344 | Fh H3_INST
345 | (
346 | .in ( hi3_w ),
347 | .out ( ho3_w )
348 | );
349 |
350 | Fg G13_INST
351 | (
352 | .in ( g1i3_w ),
353 | .out ( hi3_w[3] )
354 | );
355 |
356 | Fg G23_INST
357 | (
358 | .in ( g2i3_w ),
359 | .out ( hi3_w[2] )
360 | );
361 |
362 | Fg G33_INST
363 | (
364 | .in ( g3i3_w ),
365 | .out ( hi3_w[1] )
366 | );
367 |
368 | Fg G43_INST
369 | (
370 | .in ( g4i3_w ),
371 | .out ( hi3_w[0] )
372 | );
373 |
374 | Fa F13_INST
375 | (
376 | .in ( { key2_w[39], key2_w[31], hash2_w[39], hash2_w[31], hash2_w[23] } ),
377 | .out ( g1i3_w[3] )
378 | );
379 |
380 | Fb F23_INST
381 | (
382 | .in ( { key2_w[38], key2_w[30], hash2_w[38], hash2_w[30], hash2_w[22] } ),
383 | .out ( g1i3_w[2] )
384 | );
385 |
386 | Fa F53_INST
387 | (
388 | .in ( { key2_w[37], key2_w[29], hash2_w[37], hash2_w[29], hash2_w[21] } ),
389 | .out ( g2i3_w[3] )
390 | );
391 |
392 | Fb F63_INST
393 | (
394 | .in ( { key2_w[36], key2_w[28], hash2_w[36], hash2_w[28], hash2_w[20] } ),
395 | .out ( g2i3_w[2] )
396 | );
397 |
398 | Fa F93_INST
399 | (
400 | .in ( { key2_w[35], key2_w[27], hash2_w[35], hash2_w[27], hash2_w[19] } ),
401 | .out ( g3i3_w[3] )
402 | );
403 |
404 | Fb F103_INST
405 | (
406 | .in ( { key2_w[34], key2_w[26], hash2_w[34], hash2_w[26], hash2_w[18] } ),
407 | .out ( g3i3_w[2] )
408 | );
409 |
410 | Fa F133_INST
411 | (
412 | .in ( { key2_w[33], key2_w[25], hash2_w[33], hash2_w[25], hash2_w[17] } ),
413 | .out ( g4i3_w[3] )
414 | );
415 |
416 | Fb F143_INST
417 | (
418 | .in ( { key2_w[32], key2_w[24], hash2_w[32], hash2_w[24], hash2_w[16] } ),
419 | .out ( g4i3_w[2] )
420 | );
421 |
422 | Fc F33_INST
423 | (
424 | .in ( { key2_w[23], key2_w[15], key2_w[7], hash2_w[15], hash2_w[7] } ),
425 | .out ( g1i3_w[1] )
426 | );
427 |
428 | Fd F43_INST
429 | (
430 | .in ( { key2_w[22], key2_w[14], key2_w[6], hash2_w[14], hash2_w[6] } ),
431 | .out ( g1i3_w[0] )
432 | );
433 |
434 | Fc F73_INST
435 | (
436 | .in ( { key2_w[21], key2_w[13], key2_w[5], hash2_w[13], hash2_w[5] } ),
437 | .out ( g2i3_w[1] )
438 | );
439 |
440 | Fd F83_INST
441 | (
442 | .in ( { key2_w[20], key2_w[12], key2_w[4], hash2_w[12], hash2_w[4] } ),
443 | .out ( g2i3_w[0] )
444 | );
445 |
446 | Fc F113_INST
447 | (
448 | .in ( { key2_w[19], key2_w[11], key2_w[3], hash2_w[11], hash2_w[3] } ),
449 | .out ( g3i3_w[1] )
450 | );
451 |
452 | Fd F123_INST
453 | (
454 | .in ( { key2_w[18], key2_w[10], key2_w[2], hash2_w[10], hash2_w[2] } ),
455 | .out ( g3i3_w[0] )
456 | );
457 |
458 | Fe F153_INST
459 | (
460 | .in ( { key2_w[17], key2_w[9], key2_w[1], hash2_w[9] } ),
461 | .out ( g4i3_w[1] )
462 | );
463 |
464 | Fe F163_INST
465 | (
466 | .in ( { key2_w[16], key2_w[8], key2_w[0], hash2_w[8] } ),
467 | .out ( g4i3_w[0] )
468 | );
469 |
470 |
471 | //--------------------------------------------------------------//
472 | // Результат такта 3 //
473 |
474 | assign hash3_w = { ho3_w ^ hash2_w[1:0], hash2_w[39:2] };
475 | assign key3_w = key2_w;
476 |
477 |
478 |
479 | //==============================================================//
480 | // Синхронная схемотехника.
481 | //==============================================================//
482 |
483 | //--------------------------------------------------------------//
484 | // Защёлкивание результата в регистры.
485 |
486 | always @( posedge clock_i )
487 | begin
488 |
489 | if( run_i )
490 | begin
491 | hash_out_reg <= hash3_w;
492 | key_out_reg <= key3_w;
493 | end
494 |
495 | end
496 |
497 |
498 | endmodule
499 |
--------------------------------------------------------------------------------
/source/Fa.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fa для ядра DST40.
4 |
5 | Реализована полностью комбинаторно.
6 |
7 | ******************************************************************************/
8 |
9 | module Fa
10 | (
11 | input [4:0] in,
12 | output out
13 | );
14 |
15 | reg i;
16 | assign out = i;
17 |
18 | always @( in )
19 | begin
20 | case( in )
21 | 5'b 00000: i = 0;
22 | 5'b 00001: i = 1;
23 | 5'b 00010: i = 0;
24 | 5'b 00011: i = 1;
25 | 5'b 00100: i = 1;
26 | 5'b 00101: i = 0;
27 | 5'b 00110: i = 1;
28 | 5'b 00111: i = 1;
29 | 5'b 01000: i = 1;
30 | 5'b 01001: i = 1;
31 | 5'b 01010: i = 0;
32 | 5'b 01011: i = 0;
33 | 5'b 01100: i = 1;
34 | 5'b 01101: i = 0;
35 | 5'b 01110: i = 0;
36 | 5'b 01111: i = 0;
37 | 5'b 10000: i = 0;
38 | 5'b 10001: i = 0;
39 | 5'b 10010: i = 1;
40 | 5'b 10011: i = 1;
41 | 5'b 10100: i = 0;
42 | 5'b 10101: i = 0;
43 | 5'b 10110: i = 0;
44 | 5'b 10111: i = 1;
45 | 5'b 11000: i = 1;
46 | 5'b 11001: i = 0;
47 | 5'b 11010: i = 1;
48 | 5'b 11011: i = 0;
49 | 5'b 11100: i = 1;
50 | 5'b 11101: i = 1;
51 | 5'b 11110: i = 0;
52 | default: i = 1;
53 | endcase
54 | end
55 |
56 |
57 | endmodule
58 |
--------------------------------------------------------------------------------
/source/Fb.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fb для ядра DST40.
4 |
5 | Реализована полностью комбинаторно.
6 |
7 | ******************************************************************************/
8 |
9 | module Fb
10 | (
11 | input [4:0] in,
12 | output out
13 | );
14 |
15 |
16 | reg i;
17 | assign out = i;
18 |
19 | always @( in )
20 | begin
21 | case( in )
22 | 5'b 00000: i = 0;
23 | 5'b 00001: i = 1;
24 | 5'b 00010: i = 1;
25 | 5'b 00011: i = 0;
26 | 5'b 00100: i = 0;
27 | 5'b 00101: i = 0;
28 | 5'b 00110: i = 0;
29 | 5'b 00111: i = 0;
30 | 5'b 01000: i = 0;
31 | 5'b 01001: i = 1;
32 | 5'b 01010: i = 1;
33 | 5'b 01011: i = 0;
34 | 5'b 01100: i = 1;
35 | 5'b 01101: i = 1;
36 | 5'b 01110: i = 1;
37 | 5'b 01111: i = 1;
38 | 5'b 10000: i = 1;
39 | 5'b 10001: i = 1;
40 | 5'b 10010: i = 1;
41 | 5'b 10011: i = 1;
42 | 5'b 10100: i = 0;
43 | 5'b 10101: i = 1;
44 | 5'b 10110: i = 1;
45 | 5'b 10111: i = 0;
46 | 5'b 11000: i = 0;
47 | 5'b 11001: i = 0;
48 | 5'b 11010: i = 0;
49 | 5'b 11011: i = 0;
50 | 5'b 11100: i = 0;
51 | 5'b 11101: i = 1;
52 | 5'b 11110: i = 1;
53 | default : i = 0;
54 | endcase
55 | end
56 |
57 | endmodule
58 |
--------------------------------------------------------------------------------
/source/Fc.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fc для ядра DST40.
4 |
5 | Реализована полностью комбинаторно.
6 |
7 | ******************************************************************************/
8 |
9 | module Fc
10 | (
11 | input [4:0] in,
12 | output out
13 | );
14 |
15 |
16 | reg i;
17 | assign out = i;
18 |
19 | always @( in )
20 | begin
21 | case( in )
22 | 5'b 00000: i = 0;
23 | 5'b 00001: i = 0;
24 | 5'b 00010: i = 1;
25 | 5'b 00011: i = 0;
26 | 5'b 00100: i = 1;
27 | 5'b 00101: i = 1;
28 | 5'b 00110: i = 1;
29 | 5'b 00111: i = 0;
30 | 5'b 01000: i = 1;
31 | 5'b 01001: i = 0;
32 | 5'b 01010: i = 1;
33 | 5'b 01011: i = 1;
34 | 5'b 01100: i = 1;
35 | 5'b 01101: i = 0;
36 | 5'b 01110: i = 0;
37 | 5'b 01111: i = 0;
38 | 5'b 10000: i = 0;
39 | 5'b 10001: i = 0;
40 | 5'b 10010: i = 1;
41 | 5'b 10011: i = 1;
42 | 5'b 10100: i = 1;
43 | 5'b 10101: i = 1;
44 | 5'b 10110: i = 0;
45 | 5'b 10111: i = 0;
46 | 5'b 11000: i = 0;
47 | 5'b 11001: i = 1;
48 | 5'b 11010: i = 0;
49 | 5'b 11011: i = 1;
50 | 5'b 11100: i = 0;
51 | 5'b 11101: i = 1;
52 | 5'b 11110: i = 0;
53 | default : i = 1;
54 | endcase
55 | end
56 |
57 | endmodule
58 |
--------------------------------------------------------------------------------
/source/Fd.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fd для ядра DST40.
4 |
5 | Реализована полностью комбинаторно.
6 |
7 | ******************************************************************************/
8 |
9 | module Fd
10 | (
11 | input [4:0] in,
12 | output out
13 | );
14 |
15 |
16 | reg i;
17 | assign out = i;
18 |
19 | always @( in )
20 | begin
21 | case( in )
22 | 5'b 00000: i = 0;
23 | 5'b 00001: i = 1;
24 | 5'b 00010: i = 0;
25 | 5'b 00011: i = 1;
26 | 5'b 00100: i = 1;
27 | 5'b 00101: i = 1;
28 | 5'b 00110: i = 0;
29 | 5'b 00111: i = 0;
30 | 5'b 01000: i = 0;
31 | 5'b 01001: i = 0;
32 | 5'b 01010: i = 1;
33 | 5'b 01011: i = 1;
34 | 5'b 01100: i = 1;
35 | 5'b 01101: i = 0;
36 | 5'b 01110: i = 1;
37 | 5'b 01111: i = 0;
38 | 5'b 10000: i = 0;
39 | 5'b 10001: i = 0;
40 | 5'b 10010: i = 1;
41 | 5'b 10011: i = 1;
42 | 5'b 10100: i = 1;
43 | 5'b 10101: i = 0;
44 | 5'b 10110: i = 1;
45 | 5'b 10111: i = 0;
46 | 5'b 11000: i = 0;
47 | 5'b 11001: i = 1;
48 | 5'b 11010: i = 0;
49 | 5'b 11011: i = 1;
50 | 5'b 11100: i = 1;
51 | 5'b 11101: i = 1;
52 | 5'b 11110: i = 0;
53 | default : i = 0;
54 | endcase
55 | end
56 |
57 | endmodule
58 |
--------------------------------------------------------------------------------
/source/Fe.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fe для ядра DST40.
4 |
5 | Реализована полностью комбинаторно. Изначально было пять входов, но потом
6 | сократили до четырёх - выкинули младший вход, так как в исходной таблице
7 | все биты повторялись по два раза.
8 |
9 | ******************************************************************************/
10 |
11 | module Fe
12 | (
13 | input [3:0] in,
14 | output out
15 | );
16 |
17 | reg i;
18 | assign out = i;
19 |
20 | always @( in )
21 | begin
22 | case( in )
23 | 4'b 0000: i = 0;
24 | 4'b 0001: i = 1;
25 | 4'b 0010: i = 0;
26 | 4'b 0011: i = 1;
27 | 4'b 0100: i = 0;
28 | 4'b 0101: i = 0;
29 | 4'b 0110: i = 1;
30 | 4'b 0111: i = 1;
31 | 4'b 1000: i = 1;
32 | 4'b 1001: i = 1;
33 | 4'b 1010: i = 0;
34 | 4'b 1011: i = 0;
35 | 4'b 1100: i = 1;
36 | 4'b 1101: i = 0;
37 | 4'b 1110: i = 1;
38 | default : i = 0;
39 | endcase
40 | end
41 |
42 | endmodule
43 |
--------------------------------------------------------------------------------
/source/Fg.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fg для ядра DST40.
4 |
5 | Реализована полностью комбинаторно.
6 |
7 | ******************************************************************************/
8 |
9 | module Fg
10 | (
11 | input [3:0] in,
12 | output out
13 | );
14 |
15 |
16 | reg i;
17 | assign out = i;
18 |
19 | always @( in )
20 | begin
21 | case( in )
22 | 4'b 0000: i = 0;
23 | 4'b 0001: i = 1;
24 | 4'b 0010: i = 1;
25 | 4'b 0011: i = 1;
26 | 4'b 0100: i = 0;
27 | 4'b 0101: i = 0;
28 | 4'b 0110: i = 1;
29 | 4'b 0111: i = 0;
30 | 4'b 1000: i = 0;
31 | 4'b 1001: i = 1;
32 | 4'b 1010: i = 0;
33 | 4'b 1011: i = 0;
34 | 4'b 1100: i = 1;
35 | 4'b 1101: i = 1;
36 | 4'b 1110: i = 1;
37 | default : i = 0;
38 | endcase
39 | end
40 |
41 |
42 | endmodule
43 |
--------------------------------------------------------------------------------
/source/Fh.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Функция Fh для ядра DST40.
4 |
5 | Реализована полностью комбинаторно.
6 |
7 | ******************************************************************************/
8 |
9 | module Fh
10 | (
11 | input [3:0] in,
12 | output [1:0] out
13 | );
14 |
15 |
16 | reg [1:0] i;
17 |
18 | assign out = i;
19 |
20 | always @( in )
21 | begin
22 | case( in )
23 | 4'b 0000: i = 2'b 00;
24 | 4'b 0001: i = 2'b 00;
25 | 4'b 0010: i = 2'b 10;
26 | 4'b 0011: i = 2'b 11;
27 | 4'b 0100: i = 2'b 11;
28 | 4'b 0101: i = 2'b 01;
29 | 4'b 0110: i = 2'b 10;
30 | 4'b 0111: i = 2'b 01;
31 | 4'b 1000: i = 2'b 01;
32 | 4'b 1001: i = 2'b 10;
33 | 4'b 1010: i = 2'b 01;
34 | 4'b 1011: i = 2'b 11;
35 | 4'b 1100: i = 2'b 11;
36 | 4'b 1101: i = 2'b 10;
37 | 4'b 1110: i = 2'b 00;
38 | default : i = 2'b 00;
39 | endcase
40 | end
41 |
42 |
43 | endmodule
44 |
--------------------------------------------------------------------------------
/source/KernelXX.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Одно ядро DST40 для использования в массиве из XX ядер (больше одного).
4 |
5 | ******************************************************************************/
6 |
7 | module KernelXX
8 | #(
9 | parameter NK = 2, // Количество хэширующих ядер в составе модуля
10 | parameter L2NK = 1, // Логарифм по основанию 2 от количества ядер
11 | parameter [L2NK-1:0] ADDRESS = 0 // Адрес ядра (а фактически - старшие биты ключа)
12 | )
13 | (
14 | input clock_i, // Такты
15 | input run_i, // Разрешение работы
16 | input [39-L2NK:0] key_i, // Ключ
17 | input [39:0] challenge_i, // Запрос
18 | input [23:0] response_i, // Ожидаемый ответ
19 | output comparator_o // Выход компаратора (1 - результат совпал с ожидаемым ответом)
20 | );
21 |
22 |
23 |
24 |
25 | //==============================================================//
26 | // Внутренние провода/регистры
27 | //==============================================================//
28 |
29 | wire [39:0] last_hash_w;
30 |
31 |
32 |
33 | //==============================================================//
34 | // Комбинаторная схемотехника
35 | //==============================================================//
36 |
37 | //--------------------------------------------------------------//
38 | // Блок из 64 последовательных модулей Block64 //
39 |
40 | genvar i;
41 |
42 | generate
43 |
44 | for( i=0; i < 64; i=i+1 )
45 | begin: blk64
46 |
47 | wire [39:0] hash_w;
48 | wire [39:0] key_w;
49 |
50 | if( !i )
51 | begin
52 | Block64 BLOCK64_INST
53 | (
54 | .clock_i ( clock_i ), // Такты
55 | .run_i ( run_i ), // Разрешение работы
56 | .hash_i ( challenge_i ), // Входной хэш (такт 0)
57 | .key_i ( { ADDRESS, key_i } ), // Входной ключ (такт 0)
58 | .hash_o ( hash_w ),
59 | .key_o ( key_w )
60 | );
61 | end
62 | else if( i < 63 )
63 | begin
64 | Block64 BLOCK64_INST
65 | (
66 | .clock_i ( clock_i ),
67 | .run_i ( run_i ),
68 | .hash_i ( blk64[i-1].hash_w ),
69 | .key_i ( blk64[i-1].key_w ),
70 | .hash_o ( hash_w ),
71 | .key_o ( key_w )
72 | );
73 | end
74 | else
75 | begin
76 | Block64 BLOCK64_INST
77 | (
78 | .clock_i ( clock_i ),
79 | .run_i ( run_i ),
80 | .hash_i ( blk64[i-1].hash_w ),
81 | .key_i ( blk64[i-1].key_w ),
82 | .hash_o ( last_hash_w )
83 | );
84 | end
85 | end
86 | endgenerate
87 |
88 |
89 | assign comparator_o = ( response_i == last_hash_w[39:16] );
90 |
91 |
92 | endmodule
93 |
--------------------------------------------------------------------------------
/source/conv.bat:
--------------------------------------------------------------------------------
1 | c:\altera\14.0\quartus\bin64\quartus_cpf.exe -c --option=opt.txt ..\output_files\dst40.sof ..\output_files\dst40.rbf
2 | pause
3 |
--------------------------------------------------------------------------------
/source/dst40.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Модуль DST40.
4 |
5 | Версия 3: с развёрнутым циклом хэширования, преобразованным в 64-тактовый
6 | конвеер.
7 |
8 | 1. Интерфейс с пользователем реализован на стороне HPS.
9 |
10 | 2. Вторая проверка ключа с другими запросом/ответом запускается программно
11 | процессором HPS.
12 |
13 | 3. Флаг прерывания IRQ0 взводится в момент взведения любого из флагов -
14 | ключ найден или ключ не найден, а сбрасывается записью в любой
15 | Avalon-регистр.
16 |
17 | 4. HPS пишет/читает регистры с исходными данными через мост Avalon MM,
18 | подключенный к мосту HPS-FPGA шириной 64 бита.
19 | Адресация регистров выполняется блоками по 8 байт на 1 адрес.
20 | При чтении регистров неиспользуемые старшие биты зануляются,
21 | что упрощает дальнейшее использование данных в программе.
22 |
23 | Адресная карта:
24 |
25 | 0 - challenge ( 40 бит, Чтение/Запись ) Запрос
26 | 1 - response ( 24 бита, Чтение/Запись ) Ответ
27 | 2 - start_key ( 40 бит, Чтение/Запись ) Ключ, с которого начинать поиск
28 | 3 - run ( 1 бит, Чтение/Запись ) Флаг запуска поиска
29 | 4 - флаги:
30 | бит 0 - key_found_w ( 1 бит, Только чтение ) Флаг "ключ найден"
31 | бит 8 - key_not_found_w ( 1 бит, Только чтение ) Флаг "ключ не найден"
32 | 5 - key ( 40-L2NK бит, Только чтение ) Найденный ключ (младшие биты)
33 | 6 - kernels ( NK бит, Только чтение ) Биты ядер, нашедших ключ
34 |
35 | ******************************************************************************/
36 |
37 | module dst40
38 | (
39 | input FPGA_CLK1_50, // Такты 50 МГц
40 | input [1:0] KEY, // Кнопки
41 | input [3:0] SW, // Переключатели
42 | output [7:0] LED, // Светодиоды
43 | inout [35:0] GPIO_0, // Ножки GPIO0
44 | inout [35:0] GPIO_1, // Ножки GPIO1
45 | inout [14:0] ARDUINO_IO, // Ножки Arduino
46 |
47 | // HPS
48 |
49 | inout HPS_CONV_USB_N,
50 |
51 | output [14:0] HPS_DDR3_ADDR,
52 | output [2:0] HPS_DDR3_BA,
53 | output HPS_DDR3_CAS_N,
54 | output HPS_DDR3_CKE,
55 | output HPS_DDR3_CK_N,
56 | output HPS_DDR3_CK_P,
57 | output HPS_DDR3_CS_N,
58 | output [3:0] HPS_DDR3_DM,
59 | inout [31:0] HPS_DDR3_DQ,
60 | inout [3:0] HPS_DDR3_DQS_N,
61 | inout [3:0] HPS_DDR3_DQS_P,
62 | output HPS_DDR3_ODT,
63 | output HPS_DDR3_RAS_N,
64 | output HPS_DDR3_RESET_N,
65 | input HPS_DDR3_RZQ,
66 | output HPS_DDR3_WE_N,
67 |
68 | output HPS_ENET_GTX_CLK,
69 | inout HPS_ENET_INT_N,
70 | output HPS_ENET_MDC,
71 | inout HPS_ENET_MDIO,
72 | input HPS_ENET_RX_CLK,
73 | input [3:0] HPS_ENET_RX_DATA,
74 | input HPS_ENET_RX_DV,
75 | output [3:0] HPS_ENET_TX_DATA,
76 | output HPS_ENET_TX_EN,
77 |
78 | inout HPS_GSENSOR_INT,
79 |
80 | inout HPS_I2C0_SCLK,
81 | inout HPS_I2C0_SDAT,
82 | inout HPS_I2C1_SCLK,
83 | inout HPS_I2C1_SDAT,
84 |
85 | inout HPS_KEY,
86 | inout HPS_LED,
87 | inout HPS_LTC_GPIO,
88 |
89 | output HPS_SD_CLK,
90 | inout HPS_SD_CMD,
91 | inout [3:0] HPS_SD_DATA,
92 |
93 | output HPS_SPIM_CLK,
94 | input HPS_SPIM_MISO,
95 | output HPS_SPIM_MOSI,
96 | inout HPS_SPIM_SS,
97 |
98 | input HPS_UART_RX,
99 | output HPS_UART_TX,
100 |
101 | input HPS_USB_CLKOUT,
102 | inout [7:0] HPS_USB_DATA,
103 | input HPS_USB_DIR,
104 | input HPS_USB_NXT,
105 | output HPS_USB_STP
106 | );
107 |
108 |
109 |
110 | //==============================================================//
111 | // Параметры
112 | //==============================================================//
113 |
114 | parameter NK = 4; // Количество ядер в составе модуля
115 | parameter L2NK = log2(NK); // Логарифм по основанию 2 от NK
116 |
117 |
118 |
119 | //==============================================================//
120 | // Функции
121 | //==============================================================//
122 |
123 | //--------------------------------------------------------------//
124 | // Логарифм по основанию 2 //
125 |
126 | function integer log2;
127 | input [31:0] value;
128 | begin
129 | value = value - 1;
130 |
131 | for( log2 = 0; value > 0; log2 = log2 + 1 )
132 | value = value >> 1;
133 | end
134 | endfunction
135 |
136 |
137 |
138 | //==============================================================//
139 | // Внутренние провода/регистры
140 | //==============================================================//
141 |
142 | // Провода для соединения с PLL //
143 |
144 | wire pll_clock_main_w; // Такты для топ-модуля
145 | // wire pll_clock_oscill_w; // Такты для осциллографа (SignalTap)
146 |
147 | // Провода для соединения авалоновского моста с нашим модулем //
148 |
149 | wire [63:0] mmb_readdata_w; // Данные от нас к HPS
150 | wire [63:0] mmb_writedata_w; // Данные от HPS к нам
151 | wire [6:0] mmb_address_w; // Шина адреса
152 | wire mmb_write_w; // Строб записи
153 | wire mmb_read_w; // Строб чтения
154 | wire [7:0] mmb_byteenable_w; // Биты разрешения записи
155 |
156 | // Исходные данные - записываются процессором HPS //
157 |
158 | reg [39:0] challenge_reg = 0; // Запрос
159 | reg [23:0] response_reg = 0; // Ответ
160 | reg [39:0] start_key_reg = 0; // Стартовый ключ
161 | reg run_reg = 0; // Разрешение работы ядер
162 |
163 | // Результаты поиска //
164 |
165 | wire key_found_w; // Флаг "Ключ найден"
166 | wire key_not_found_w; // Флаг "Работа завершена - ключ не найден"
167 | wire [NK-1:0] kernels_w; // Биты, показывающие какое ядро (или ядра), нашло ключ
168 | wire [39-L2NK:0] result_w; // Найденный ключ
169 |
170 | reg irq_reg = 0; // Флаг прерывания
171 |
172 |
173 |
174 | //==============================================================//
175 | // Комбинаторная схемотехника
176 | //==============================================================//
177 |
178 | assign GPIO_0 = 36'h ZZZZZZZZZ;
179 | assign GPIO_1 = 36'h ZZZZZZZZZ;
180 |
181 | assign LED[7:1] = 7'b 0000000;
182 | assign LED[0] = key_found_w;
183 |
184 |
185 |
186 | //--------------------------------------------------------------//
187 | // PLL делает такты для всей схемы и для осциллографа //
188 |
189 | pll PLL_INST
190 | (
191 | .refclk ( FPGA_CLK1_50 ), // Входные такты
192 | .rst ( 0 ), // Сброс
193 | .outclk_0 ( pll_clock_main_w ) // Такты для топ-модуля
194 | // .outclk_1 ( pll_clock_oscill_w ) // Такты для осциллографа
195 | );
196 |
197 |
198 | //--------------------------------------------------------------//
199 | // Модуль поиска ключа, включающий в себя NK хэширующих ядер //
200 |
201 | dst40_XX
202 | #(
203 | .NK ( NK ),
204 | .L2NK ( L2NK )
205 | )
206 | DST40_XX_INST
207 | (
208 | .clock_i ( pll_clock_main_w ), // Такты
209 | .challenge_i ( challenge_reg ), // Запрос
210 | .response_i ( response_reg ), // Ответ
211 | .start_key_i ( start_key_reg ), // Стартовый ключ
212 | .run_i ( run_reg ), // Разрешение работы ядер
213 | .key_found_o ( key_found_w ), // Флаг "ключ найден"
214 | .key_not_found_o ( key_not_found_w ), // Флаг "ключ не найден"
215 | .kernels_o ( kernels_w ), // Биты, показывающие какое ядро (или ядра), нашло ключ
216 | .key_o ( result_w ) // Найденный ключ (младшие биты)
217 | );
218 |
219 |
220 | //--------------------------------------------------------------//
221 | // HPS-процессор //
222 |
223 | soc_system SOC_INST
224 | (
225 | // Такты и сброс для мостов и прочей периферии
226 | .clk_clk ( FPGA_CLK1_50 ), // Такты
227 | .reset_reset_n ( 1'b 1 ), // Сброс
228 |
229 | // RAM DDR3
230 | .memory_mem_a ( HPS_DDR3_ADDR ),
231 | .memory_mem_ba ( HPS_DDR3_BA ),
232 | .memory_mem_ck ( HPS_DDR3_CK_P ),
233 | .memory_mem_ck_n ( HPS_DDR3_CK_N ),
234 | .memory_mem_cke ( HPS_DDR3_CKE ),
235 | .memory_mem_cs_n ( HPS_DDR3_CS_N ),
236 | .memory_mem_ras_n ( HPS_DDR3_RAS_N ),
237 | .memory_mem_cas_n ( HPS_DDR3_CAS_N ),
238 | .memory_mem_we_n ( HPS_DDR3_WE_N ),
239 | .memory_mem_reset_n ( HPS_DDR3_RESET_N ),
240 | .memory_mem_dq ( HPS_DDR3_DQ ),
241 | .memory_mem_dqs ( HPS_DDR3_DQS_P ),
242 | .memory_mem_dqs_n ( HPS_DDR3_DQS_N ),
243 | .memory_mem_odt ( HPS_DDR3_ODT ),
244 | .memory_mem_dm ( HPS_DDR3_DM ),
245 | .memory_oct_rzqin ( HPS_DDR3_RZQ ),
246 |
247 | // Ethernet
248 | .hps_0_hps_io_hps_io_emac1_inst_TX_CLK ( HPS_ENET_GTX_CLK ),
249 | .hps_0_hps_io_hps_io_emac1_inst_TXD0 ( HPS_ENET_TX_DATA[0] ),
250 | .hps_0_hps_io_hps_io_emac1_inst_TXD1 ( HPS_ENET_TX_DATA[1] ),
251 | .hps_0_hps_io_hps_io_emac1_inst_TXD2 ( HPS_ENET_TX_DATA[2] ),
252 | .hps_0_hps_io_hps_io_emac1_inst_TXD3 ( HPS_ENET_TX_DATA[3] ),
253 | .hps_0_hps_io_hps_io_emac1_inst_RXD0 ( HPS_ENET_RX_DATA[0] ),
254 | .hps_0_hps_io_hps_io_emac1_inst_MDIO ( HPS_ENET_MDIO ),
255 | .hps_0_hps_io_hps_io_emac1_inst_MDC ( HPS_ENET_MDC ),
256 | .hps_0_hps_io_hps_io_emac1_inst_RX_CTL ( HPS_ENET_RX_DV ),
257 | .hps_0_hps_io_hps_io_emac1_inst_TX_CTL ( HPS_ENET_TX_EN ),
258 | .hps_0_hps_io_hps_io_emac1_inst_RX_CLK ( HPS_ENET_RX_CLK ),
259 | .hps_0_hps_io_hps_io_emac1_inst_RXD1 ( HPS_ENET_RX_DATA[1] ),
260 | .hps_0_hps_io_hps_io_emac1_inst_RXD2 ( HPS_ENET_RX_DATA[2] ),
261 | .hps_0_hps_io_hps_io_emac1_inst_RXD3 ( HPS_ENET_RX_DATA[3] ),
262 |
263 | // SD-карта
264 | .hps_0_hps_io_hps_io_sdio_inst_CMD ( HPS_SD_CMD ),
265 | .hps_0_hps_io_hps_io_sdio_inst_D0 ( HPS_SD_DATA[0] ),
266 | .hps_0_hps_io_hps_io_sdio_inst_D1 ( HPS_SD_DATA[1] ),
267 | .hps_0_hps_io_hps_io_sdio_inst_CLK ( HPS_SD_CLK ),
268 | .hps_0_hps_io_hps_io_sdio_inst_D2 ( HPS_SD_DATA[2] ),
269 | .hps_0_hps_io_hps_io_sdio_inst_D3 ( HPS_SD_DATA[3] ),
270 |
271 | // USB
272 | .hps_0_hps_io_hps_io_usb1_inst_D0 ( HPS_USB_DATA[0] ),
273 | .hps_0_hps_io_hps_io_usb1_inst_D1 ( HPS_USB_DATA[1] ),
274 | .hps_0_hps_io_hps_io_usb1_inst_D2 ( HPS_USB_DATA[2] ),
275 | .hps_0_hps_io_hps_io_usb1_inst_D3 ( HPS_USB_DATA[3] ),
276 | .hps_0_hps_io_hps_io_usb1_inst_D4 ( HPS_USB_DATA[4] ),
277 | .hps_0_hps_io_hps_io_usb1_inst_D5 ( HPS_USB_DATA[5] ),
278 | .hps_0_hps_io_hps_io_usb1_inst_D6 ( HPS_USB_DATA[6] ),
279 | .hps_0_hps_io_hps_io_usb1_inst_D7 ( HPS_USB_DATA[7] ),
280 | .hps_0_hps_io_hps_io_usb1_inst_CLK ( HPS_USB_CLKOUT ),
281 | .hps_0_hps_io_hps_io_usb1_inst_STP ( HPS_USB_STP ),
282 | .hps_0_hps_io_hps_io_usb1_inst_DIR ( HPS_USB_DIR ),
283 | .hps_0_hps_io_hps_io_usb1_inst_NXT ( HPS_USB_NXT ),
284 |
285 | // SPI
286 | .hps_0_hps_io_hps_io_spim1_inst_CLK ( HPS_SPIM_CLK ),
287 | .hps_0_hps_io_hps_io_spim1_inst_MOSI ( HPS_SPIM_MOSI ),
288 | .hps_0_hps_io_hps_io_spim1_inst_MISO ( HPS_SPIM_MISO ),
289 | .hps_0_hps_io_hps_io_spim1_inst_SS0 ( HPS_SPIM_SS ),
290 |
291 | // UART
292 | .hps_0_hps_io_hps_io_uart0_inst_RX ( HPS_UART_RX ),
293 | .hps_0_hps_io_hps_io_uart0_inst_TX ( HPS_UART_TX ),
294 |
295 | // I2C1
296 | .hps_0_hps_io_hps_io_i2c0_inst_SDA ( HPS_I2C0_SDAT ),
297 | .hps_0_hps_io_hps_io_i2c0_inst_SCL ( HPS_I2C0_SCLK ),
298 |
299 | // I2C2
300 | .hps_0_hps_io_hps_io_i2c1_inst_SDA ( HPS_I2C1_SDAT ),
301 | .hps_0_hps_io_hps_io_i2c1_inst_SCL ( HPS_I2C1_SCLK ),
302 |
303 | // GPIO
304 | .hps_0_hps_io_hps_io_gpio_inst_GPIO09 ( HPS_CONV_USB_N ),
305 | .hps_0_hps_io_hps_io_gpio_inst_GPIO35 ( HPS_ENET_INT_N ),
306 | .hps_0_hps_io_hps_io_gpio_inst_GPIO40 ( HPS_LTC_GPIO ),
307 | .hps_0_hps_io_hps_io_gpio_inst_GPIO53 ( HPS_LED ),
308 | .hps_0_hps_io_hps_io_gpio_inst_GPIO54 ( HPS_KEY ),
309 | .hps_0_hps_io_hps_io_gpio_inst_GPIO61 ( HPS_GSENSOR_INT ),
310 |
311 | // Avalon Memory Mapped Bridge
312 | .mm_bridge_waitrequest ( 0 ), // Для записи в регистры нет необходимости в циклах задержки
313 | .mm_bridge_readdata ( mmb_readdata_w ), // Передаваемые в HPS данные
314 | .mm_bridge_readdatavalid ( mmb_read_w ), // При чтении из регистров данные валидны практически сразу
315 | .mm_bridge_writedata ( mmb_writedata_w ), // Передаваемые из HPS данные
316 | .mm_bridge_address ( mmb_address_w ), // Адрес 64-битного регистра
317 | .mm_bridge_write ( mmb_write_w ), // Строб записи
318 | .mm_bridge_read ( mmb_read_w ), // Строб чтения
319 | .mm_bridge_byteenable ( mmb_byteenable_w ), // Биты разрешения записи
320 |
321 | // IRQ
322 | .irq0_irq ( { 31'd 0, irq_reg } ) // Прерывание IRQ0
323 | );
324 |
325 |
326 |
327 | //--------------------------------------------------------------//
328 | // Чтение данных через интерфейс Avalon-MM //
329 | //
330 | // Неиспользуемые старшие биты зануляются, что упрощает
331 | // дальнейшее использование данных в программе.
332 |
333 | assign mmb_readdata_w = ( mmb_address_w == 7'd 0 ) ? { 24'b0, challenge_reg } :
334 | ( mmb_address_w == 7'd 1 ) ? { 40'b0, response_reg } :
335 | ( mmb_address_w == 7'd 2 ) ? { 24'b0, start_key_reg } :
336 | ( mmb_address_w == 7'd 3 ) ? { 63'b0, run_reg } :
337 | ( mmb_address_w == 7'd 4 ) ? { 55'b0, key_not_found_w, 7'b0, key_found_w } :
338 | ( mmb_address_w == 7'd 5 ) ? { {L2NK+24{1'b0}}, result_w } :
339 | ( mmb_address_w == 7'd 6 ) ? { {64-NK{1'b0}}, kernels_w } :
340 | 0;
341 |
342 |
343 |
344 | //==============================================================//
345 | // Синхронная схемотехника.
346 | //==============================================================//
347 |
348 | always @( posedge FPGA_CLK1_50 )
349 | begin
350 |
351 | //------------------------------------------------------------//
352 | // Запись в регистры через интерфейс Avalon-MM //
353 | //
354 | // Адресация выполняется блоками по 8 байт на 1 адрес,
355 | // так как ширина интерфейса 64 бита.
356 |
357 | if( mmb_write_w )
358 | begin
359 |
360 | // Запись в регистр challenge_reg
361 |
362 | if( !mmb_address_w )
363 | begin
364 | if( mmb_byteenable_w[0] )
365 | challenge_reg[7:0] <= mmb_writedata_w[7:0];
366 |
367 | if( mmb_byteenable_w[1] )
368 | challenge_reg[15:8] <= mmb_writedata_w[15:8];
369 |
370 | if( mmb_byteenable_w[2] )
371 | challenge_reg[23:16] <= mmb_writedata_w[23:16];
372 |
373 | if( mmb_byteenable_w[3] )
374 | challenge_reg[31:24] <= mmb_writedata_w[31:24];
375 |
376 | if( mmb_byteenable_w[4] )
377 | challenge_reg[39:32] <= mmb_writedata_w[39:32];
378 | end
379 |
380 | // Запись в регистр response_reg
381 |
382 | else if( mmb_address_w == 7'd 1 )
383 | begin
384 | if( mmb_byteenable_w[0] )
385 | response_reg[7:0] <= mmb_writedata_w[7:0];
386 |
387 | if( mmb_byteenable_w[1] )
388 | response_reg[15:8] <= mmb_writedata_w[15:8];
389 |
390 | if( mmb_byteenable_w[2] )
391 | response_reg[23:16] <= mmb_writedata_w[23:16];
392 | end
393 |
394 | // Запись в регистр start_key_reg
395 |
396 | else if( mmb_address_w == 7'd 2 )
397 | begin
398 | if( mmb_byteenable_w[0] )
399 | start_key_reg[7:0] <= mmb_writedata_w[7:0];
400 |
401 | if( mmb_byteenable_w[1] )
402 | start_key_reg[15:8] <= mmb_writedata_w[15:8];
403 |
404 | if( mmb_byteenable_w[2] )
405 | start_key_reg[23:16] <= mmb_writedata_w[23:16];
406 |
407 | if( mmb_byteenable_w[3] )
408 | start_key_reg[31:24] <= mmb_writedata_w[31:24];
409 |
410 | if( mmb_byteenable_w[4] )
411 | start_key_reg[39:32] <= mmb_writedata_w[39:32];
412 | end
413 |
414 | // Запись в регистр run_reg
415 |
416 | else if( mmb_address_w == 7'd 3 )
417 | begin
418 | if( mmb_byteenable_w[0] )
419 | run_reg <= mmb_writedata_w[0];
420 | end
421 |
422 | irq_reg <= 0; // По любой записи в любой регистр сбрасываем флаг прерывания
423 |
424 | end
425 | else
426 | begin
427 |
428 | if( run_reg && ( key_found_w || key_not_found_w ) ) // Если поиск запущен и взвёлся любой из битов результата поиска,
429 | irq_reg <= 1; // то взводим флаг прерывания.
430 |
431 | end
432 |
433 | end
434 |
435 |
436 | endmodule
437 |
--------------------------------------------------------------------------------
/source/dst40_XX.v:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 |
3 | Модуль DST40 - объединяет в себе XX ядер (больше одного).
4 |
5 | ПРИМЕЧАНИЯ.
6 |
7 | 1. Сигнал run_i формируется программно из HPS, следовательно он асинхронен
8 | по отношению к нашему модулю. Поэтому для исключения сбоев выполняется
9 | синхронизация этого сигнала с нашими тактами.
10 |
11 | ******************************************************************************/
12 |
13 | module dst40_XX
14 | #(
15 | parameter NK = 2, // Количество хэширующих ядер в составе модуля
16 | parameter L2NK = 1 // Логарифм по основанию 2 от количества ядер
17 | )
18 | (
19 | input clock_i, // Такты
20 | input [39:0] challenge_i, // Запрос
21 | input [23:0] response_i, // Ответ
22 | input [39:0] start_key_i, // Стартовый ключ
23 | input run_i, // Разрешение поиска ключа
24 | output key_found_o, // Флаг "ключ найден"
25 | output key_not_found_o, // Флаг "работа закончена - ключ не найден"
26 | output [NK-1:0] kernels_o, // Биты компараторов: 1 укажет на ядро, нашедшее ключ (или несколько 1 укажет на несколько ядер)
27 | output [39-L2NK:0] key_o // Результат поиска: младшие биты найденного ключа
28 | );
29 |
30 |
31 |
32 | //==============================================================//
33 | // Внутренние провода/регистры
34 | //==============================================================//
35 |
36 | // Текущие рабочие регистры
37 |
38 | reg [40-L2NK:0] key_reg = 0; // Перебираемые ключи
39 | reg [39:0] challenge_reg = 0; // Текущий запрос
40 | reg [23:0] response_reg = 0; // Текущий ответ
41 | reg [1:0] run_reg = 0; // Регистр для синхронизации сигнала RUN с нашими тактами
42 |
43 | reg [6:0] tick_reg = 0; // Номер текущего такта
44 |
45 | // Результаты хэширования
46 |
47 | wire [NK-1:0] comparators_w; // Результаты работы ядер (валидны только начиная с такта 64)
48 |
49 |
50 |
51 | //==============================================================//
52 | // Комбинаторная схемотехника
53 | //==============================================================//
54 |
55 | wire key_found_w = ( tick_reg[6] && comparators_w != 0 );// Флаг "ключ найден": 1 если ключ найден
56 |
57 | wire key_not_found_w = key_reg[40-L2NK] & key_reg[6]; // Флаг "работа закончена - ключ не найден"
58 |
59 | wire run_w = run_reg[1] & ~key_found_o & ~key_not_found_o; // Разрешение работы ядер
60 |
61 | assign key_found_o = key_found_w; // Вывод флага "ключ найден" в порт key_found_o
62 | assign key_not_found_o = key_not_found_w; // Флаг "ключ не найден": 1 если все ключи перебраны и ключ не найден
63 | assign key_o = key_reg[39-L2NK:0] - 40'd 64; // Вывод в порт key_o младших бит найденного ключа
64 | assign kernels_o = comparators_w; // Биты ядер, нашедших ключ
65 |
66 |
67 |
68 | //--------------------------------------------------------------//
69 | // Блок из XX ядер //
70 |
71 | genvar i;
72 |
73 | generate
74 |
75 | for( i=0; i < NK; i=i+1 )
76 | begin: _kernels_
77 |
78 | KernelXX
79 | #(
80 | .NK ( NK ), // Количество ядер
81 | .L2NK ( L2NK ), // Логарифм по основанию 2 от количества ядер
82 | .ADDRESS ( i ) // Номер ядра - фактически старшие биты ключа
83 | )
84 | KERNEL32_INST
85 | (
86 | .clock_i ( clock_i ), // Такты для конвеера
87 | .run_i ( run_w ), // Разрешение работы ядер
88 | .key_i ( key_reg[39-L2NK:0] ), // Ключ
89 | .challenge_i ( challenge_reg ), // Запрос
90 | .response_i ( response_reg ), // Ожидаемый ответ
91 | .comparator_o ( comparators_w[i] ) // Выход компаратора (1 - результат совпал с ожидаемым ответом)
92 | );
93 |
94 | end
95 |
96 | endgenerate
97 |
98 |
99 |
100 | //==============================================================//
101 | // Синхронная схемотехника.
102 | //==============================================================//
103 |
104 | //--------------------------------------------------------------//
105 | // Основной рабочий процесс - поиск ключа.
106 |
107 | always @( posedge clock_i )
108 | begin
109 |
110 | run_reg <= { run_reg[0], run_i }; // Синхронизируем входной сигнал run_i с нашими тактами
111 |
112 | // Перебор ключей
113 |
114 | if( run_reg[1] ) // Выполняем поиск ключа пока разрешено.
115 | begin
116 | if( !tick_reg[6] ) // Инкрементируем номер такта, пока он не достигнет числа 64:
117 | tick_reg <= tick_reg + 1; // начиная с этого момента выходные данные считаются валидными.
118 |
119 | if( !key_not_found_w && !key_found_w ) // Выполняем работу по поиску только если перебраны не все ключи
120 | key_reg <= key_reg + 40'd 1; // и не найден подходящий ключ.
121 | end
122 |
123 | // Ожидание старта // В режиме ожидания готовим схему к старту поиска
124 |
125 | else
126 | begin
127 | tick_reg <= 0; // Обнуляем номер такта (очищаем очередь конвеера)
128 | challenge_reg <= challenge_i;
129 | response_reg <= response_i;
130 | key_reg <= { 1'b 0, start_key_i[39-L2NK:0] };
131 | end
132 | end
133 |
134 |
135 | endmodule
136 |
--------------------------------------------------------------------------------
/source/opt.txt:
--------------------------------------------------------------------------------
1 | Bitstream_compression=on
2 |
--------------------------------------------------------------------------------
/source/pll.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %Altera PLL v14.0%
2 | // GENERATION: XML
3 | // pll.v
4 |
5 | // Generated using ACDS version 14.0 200 at 2015.09.02.13:34:39
6 |
7 | `timescale 1 ps / 1 ps
8 | module pll (
9 | input wire refclk, // refclk.clk
10 | input wire rst, // reset.reset
11 | output wire outclk_0 // outclk0.clk
12 | );
13 |
14 | pll_0002 pll_inst (
15 | .refclk (refclk), // refclk.clk
16 | .rst (rst), // reset.reset
17 | .outclk_0 (outclk_0), // outclk0.clk
18 | .locked () // (terminated)
19 | );
20 |
21 | endmodule
22 | // Retrieval info:
23 | //
48 | // Retrieval info:
49 | // Retrieval info:
50 | // Retrieval info:
51 | // Retrieval info:
52 | // Retrieval info:
53 | // Retrieval info:
54 | // Retrieval info:
55 | // Retrieval info:
56 | // Retrieval info:
57 | // Retrieval info:
58 | // Retrieval info:
59 | // Retrieval info:
60 | // Retrieval info:
61 | // Retrieval info:
62 | // Retrieval info:
63 | // Retrieval info:
64 | // Retrieval info:
65 | // Retrieval info:
66 | // Retrieval info:
67 | // Retrieval info:
68 | // Retrieval info:
69 | // Retrieval info:
70 | // Retrieval info:
71 | // Retrieval info:
72 | // Retrieval info:
73 | // Retrieval info:
74 | // Retrieval info:
75 | // Retrieval info:
76 | // Retrieval info:
77 | // Retrieval info:
78 | // Retrieval info:
79 | // Retrieval info:
80 | // Retrieval info:
81 | // Retrieval info:
82 | // Retrieval info:
83 | // Retrieval info:
84 | // Retrieval info:
85 | // Retrieval info:
86 | // Retrieval info:
87 | // Retrieval info:
88 | // Retrieval info:
89 | // Retrieval info:
90 | // Retrieval info:
91 | // Retrieval info:
92 | // Retrieval info:
93 | // Retrieval info:
94 | // Retrieval info:
95 | // Retrieval info:
96 | // Retrieval info:
97 | // Retrieval info:
98 | // Retrieval info:
99 | // Retrieval info:
100 | // Retrieval info:
101 | // Retrieval info:
102 | // Retrieval info:
103 | // Retrieval info:
104 | // Retrieval info:
105 | // Retrieval info:
106 | // Retrieval info:
107 | // Retrieval info:
108 | // Retrieval info:
109 | // Retrieval info:
110 | // Retrieval info:
111 | // Retrieval info:
112 | // Retrieval info:
113 | // Retrieval info:
114 | // Retrieval info:
115 | // Retrieval info:
116 | // Retrieval info:
117 | // Retrieval info:
118 | // Retrieval info:
119 | // Retrieval info:
120 | // Retrieval info:
121 | // Retrieval info:
122 | // Retrieval info:
123 | // Retrieval info:
124 | // Retrieval info:
125 | // Retrieval info:
126 | // Retrieval info:
127 | // Retrieval info:
128 | // Retrieval info:
129 | // Retrieval info:
130 | // Retrieval info:
131 | // Retrieval info:
132 | // Retrieval info:
133 | // Retrieval info:
134 | // Retrieval info:
135 | // Retrieval info:
136 | // Retrieval info:
137 | // Retrieval info:
138 | // Retrieval info:
139 | // Retrieval info:
140 | // Retrieval info:
141 | // Retrieval info:
142 | // Retrieval info:
143 | // Retrieval info:
144 | // Retrieval info:
145 | // Retrieval info:
146 | // Retrieval info:
147 | // Retrieval info:
148 | // Retrieval info:
149 | // Retrieval info:
150 | // Retrieval info:
151 | // Retrieval info:
152 | // Retrieval info:
153 | // Retrieval info:
154 | // Retrieval info:
155 | // Retrieval info:
156 | // Retrieval info:
157 | // Retrieval info:
158 | // Retrieval info:
159 | // Retrieval info:
160 | // Retrieval info:
161 | // Retrieval info:
162 | // Retrieval info:
163 | // Retrieval info:
164 | // Retrieval info:
165 | // Retrieval info:
166 | // Retrieval info:
167 | // Retrieval info:
168 | // Retrieval info:
169 | // Retrieval info:
170 | // Retrieval info:
171 | // Retrieval info:
172 | // Retrieval info:
173 | // Retrieval info:
174 | // Retrieval info:
175 | // Retrieval info:
176 | // Retrieval info:
177 | // Retrieval info:
178 | // Retrieval info:
179 | // Retrieval info:
180 | // Retrieval info:
181 | // Retrieval info:
182 | // Retrieval info:
183 | // Retrieval info:
184 | // Retrieval info:
185 | // Retrieval info:
186 | // Retrieval info:
187 | // Retrieval info:
188 | // Retrieval info:
189 | // Retrieval info:
190 | // Retrieval info:
191 | // Retrieval info:
192 | // Retrieval info:
193 | // Retrieval info:
194 | // Retrieval info:
195 | // Retrieval info:
196 | // Retrieval info:
197 | // Retrieval info:
198 | // Retrieval info:
199 | // Retrieval info:
200 | // Retrieval info:
201 | // Retrieval info:
202 | // Retrieval info:
203 | // Retrieval info:
204 | // Retrieval info:
205 | // Retrieval info:
206 | // Retrieval info:
207 | // Retrieval info:
208 | // Retrieval info:
209 | // Retrieval info:
210 | // Retrieval info:
211 | // Retrieval info:
212 | // Retrieval info:
213 | // Retrieval info:
214 | // Retrieval info:
215 | // Retrieval info:
216 | // Retrieval info:
217 | // Retrieval info:
218 | // Retrieval info:
219 | // Retrieval info:
220 | // Retrieval info:
221 | // Retrieval info:
222 | // Retrieval info:
223 | // Retrieval info:
224 | // Retrieval info:
225 | // Retrieval info:
226 | // Retrieval info:
227 | // Retrieval info:
228 | // Retrieval info:
229 | // Retrieval info:
230 | // Retrieval info:
231 | // Retrieval info:
232 | // Retrieval info:
233 | // Retrieval info:
234 | // Retrieval info:
235 | // Retrieval info:
236 | // Retrieval info:
237 | // Retrieval info:
238 | // Retrieval info:
239 | // Retrieval info:
240 | // Retrieval info:
241 | // Retrieval info:
242 | // Retrieval info:
243 | // Retrieval info:
244 | // Retrieval info:
245 | // Retrieval info:
246 | // Retrieval info:
247 | // Retrieval info:
248 | // Retrieval info:
249 | // Retrieval info:
250 | // Retrieval info:
251 | // Retrieval info:
252 | // Retrieval info:
253 | // IPFS_FILES : pll.vo
254 | // RELATED_FILES: pll.v, pll_0002.v
255 |
--------------------------------------------------------------------------------
/source/pll/pll_0002.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*"
2 |
3 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*"
4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*"
5 |
--------------------------------------------------------------------------------
/source/pll/pll_0002.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 | module pll_0002(
3 |
4 | // interface 'refclk'
5 | input wire refclk,
6 |
7 | // interface 'reset'
8 | input wire rst,
9 |
10 | // interface 'outclk0'
11 | output wire outclk_0,
12 |
13 | // interface 'locked'
14 | output wire locked
15 | );
16 |
17 | altera_pll #(
18 | .fractional_vco_multiplier("false"),
19 | .reference_clock_frequency("50.0 MHz"),
20 | .operation_mode("direct"),
21 | .number_of_clocks(1),
22 | .output_clock_frequency0("150.000000 MHz"),
23 | .phase_shift0("0 ps"),
24 | .duty_cycle0(50),
25 | .output_clock_frequency1("0 MHz"),
26 | .phase_shift1("0 ps"),
27 | .duty_cycle1(50),
28 | .output_clock_frequency2("0 MHz"),
29 | .phase_shift2("0 ps"),
30 | .duty_cycle2(50),
31 | .output_clock_frequency3("0 MHz"),
32 | .phase_shift3("0 ps"),
33 | .duty_cycle3(50),
34 | .output_clock_frequency4("0 MHz"),
35 | .phase_shift4("0 ps"),
36 | .duty_cycle4(50),
37 | .output_clock_frequency5("0 MHz"),
38 | .phase_shift5("0 ps"),
39 | .duty_cycle5(50),
40 | .output_clock_frequency6("0 MHz"),
41 | .phase_shift6("0 ps"),
42 | .duty_cycle6(50),
43 | .output_clock_frequency7("0 MHz"),
44 | .phase_shift7("0 ps"),
45 | .duty_cycle7(50),
46 | .output_clock_frequency8("0 MHz"),
47 | .phase_shift8("0 ps"),
48 | .duty_cycle8(50),
49 | .output_clock_frequency9("0 MHz"),
50 | .phase_shift9("0 ps"),
51 | .duty_cycle9(50),
52 | .output_clock_frequency10("0 MHz"),
53 | .phase_shift10("0 ps"),
54 | .duty_cycle10(50),
55 | .output_clock_frequency11("0 MHz"),
56 | .phase_shift11("0 ps"),
57 | .duty_cycle11(50),
58 | .output_clock_frequency12("0 MHz"),
59 | .phase_shift12("0 ps"),
60 | .duty_cycle12(50),
61 | .output_clock_frequency13("0 MHz"),
62 | .phase_shift13("0 ps"),
63 | .duty_cycle13(50),
64 | .output_clock_frequency14("0 MHz"),
65 | .phase_shift14("0 ps"),
66 | .duty_cycle14(50),
67 | .output_clock_frequency15("0 MHz"),
68 | .phase_shift15("0 ps"),
69 | .duty_cycle15(50),
70 | .output_clock_frequency16("0 MHz"),
71 | .phase_shift16("0 ps"),
72 | .duty_cycle16(50),
73 | .output_clock_frequency17("0 MHz"),
74 | .phase_shift17("0 ps"),
75 | .duty_cycle17(50),
76 | .pll_type("General"),
77 | .pll_subtype("General")
78 | ) altera_pll_i (
79 | .rst (rst),
80 | .outclk ({outclk_0}),
81 | .locked (locked),
82 | .fboutclk ( ),
83 | .fbclk (1'b0),
84 | .refclk (refclk)
85 | );
86 | endmodule
87 |
88 |
--------------------------------------------------------------------------------
/source/soc_system.qsys:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | 0x000000000000000000
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 | Bidirectional,Bidirectional,Bidirectional,Bidirectional,Bidirectional,Bidirectional
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 | {320000000 1600000000} {320000000 1000000000} {800000000 400000000 400000000}
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 | No,No,No,No,No,No,No,No
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 | No,No,No,No,No,No,No,No,No,Yes,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,Yes,No,No,No,No,Yes,No,No,No,No,No,No,No,No,No,No,No,No,Yes,Yes,No,No,No,No,No,No,Yes,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No
548 | No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
593 |
596 |
597 |
598 |
599 |
602 |
603 |
604 |
605 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
629 |
630 |
631 |
632 |
633 |
634 |
639 |
644 |
649 |
654 |
655 |
656 |
657 |
--------------------------------------------------------------------------------