├── 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 | 26 | 27 | 32 | 36 | 39 | 40 | 41 | 42 | 43 | 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 | 79 | 80 | 86 | 89 | 92 | 93 | 94 | 95 | 96 | 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 | 26 | 27 | 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 | 77 | 78 | 83 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 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 | --------------------------------------------------------------------------------