{"id":460094,"date":"2025-05-18T21:00:13","date_gmt":"2025-05-18T21:00:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=460094"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=460094","title":{"rendered":"<span>\u041f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435 \u0447.2<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/qq\/ea\/92\/qqea92hmnawa34pzq8yvmon9id0.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/qq\/ea\/92\/qqea92hmnawa34pzq8yvmon9id0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/qq\/ea\/92\/qqea92hmnawa34pzq8yvmon9id0.png 781w\" loading=\"lazy\" decode=\"async\"\/><br \/> \u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/909700\/\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u044f\u0434\u0440\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c. \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0443\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e. \u0415\u0449\u0451 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438. <a name=\"habracut\"><\/a><\/p>\n<h2>\u0418\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b<\/h2>\n<p> \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u043a \u0431\u044b\u043b \u0435\u0449\u0451 \u0438 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0439, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u0441\u0442 CoreMark. \u041a\u0430\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u0441 <a href=\"https:\/\/github.com\/eembc\/coremark\" rel=\"nofollow noopener noreferrer\">\u0433\u0438\u0442\u0445\u0430\u0431\u0430<\/a>. \u0421\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/xpack-dev-tools.github.io\/\" rel=\"nofollow noopener noreferrer\">gcc \u0434\u043b\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b Risc-V<\/a>. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0438\u0441\u0442\u044b\u0439 \u043a\u043e\u0434, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u043e\u043c\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445, \u0438 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u043c\u0435\u0441\u0442\u043e, \u043d\u0438\u043a\u0430\u043a\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<br \/> \u0412 \u0441\u0430\u043c\u043e\u043c \u0442\u0435\u0441\u0442\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 core_portme.h \u043d\u0430\u0434\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0431\u043e\u0440\u043a\u0438. <\/p>\n<pre><code class=\"cpp\">#define HAS_FLOAT 0 \/\/ \u043c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0443\u043c\u0435\u0435\u043c \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 #define HAS_TIME_H 0 \/\/ \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0448\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c #define USE_CLOCK 0 #define MAIN_HAS_NOARGC 1 \/\/\u043d\u0443 \u0438 \u0432 main \u043c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u043c, \u0438\u0431\u043e \u043d\u0435\u043e\u0442\u043a\u0443\u0434\u0430 <\/code><\/pre>\n<p> \u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0432 core_portme.c \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u0430. \u0421\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0430\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0432\u0430\u0436\u043d\u043e, \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0432\u043b\u0435\u0437\u0442\u044c. \u0412 \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u043e\u043c \u0442\u0430\u0439\u043c\u0435\u0440\u0435 \u0435\u0449\u0451 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u043c, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0432 \u0436\u0435\u043b\u0435\u0437\u0435, \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f. <\/p>\n<pre><code class=\"cpp\">#define CLOCKS_PER_SEC 100 <\/code><\/pre>\n<p> \u0412 ee_printf.c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 uart_send_char \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b \u043f\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0435 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430. \u0421 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u0447\u0438\u0442\u0430\u0435\u043c \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0430\u043c\u0438 \u0437\u0430\u0434\u0430\u043b\u0438. <\/p>\n<pre><code class=\"cpp\">void uart_send_char(char c) { *((volatile int*)0x40000004) = c; }  CORETIMETYPE barebones_clock() { return *((volatile int*)0x40000008); } <\/code><\/pre>\n<p> \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043a\u0438 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u0432\u043e\u0434\u0438\u043c boot.s \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u0442\u0443\u0434\u0430 main \u0440\u0443\u043a\u0430\u043c\u0438. <\/p>\n<pre><code class=\"cpp\">.globl  _start  _start: la   sp, _stack la   gp, _global call  main <\/code><\/pre>\n<p> \u0410\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430 \u0442\u043e\u0436\u0435 \u043d\u0435\u0442, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043d\u0430\u043a\u0438\u0434\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">mylib.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">unsigned __umulsi3(unsigned a, unsigned b) { unsigned result = 0;  while (b) { if (b &amp; 1) result += a; a &lt;&lt;= 1; b &gt;&gt;= 1; }  return result; }  int __mulsi3(int a, int b) { unsigned sign = 0;  if (a &lt; 0) { sign ^= 1; a = -a; }  if (b &lt; 0) { sign ^= 1; b = -b; }  unsigned result = __umulsi3(a, b);  return sign ? -result : result; }  unsigned __udivmod(unsigned a, unsigned b, int var) { if (b == 0) return 0;  unsigned msb = 1; while(b &lt; a &amp;&amp; !(b &amp; (1&lt;&lt;31))) { msb &lt;&lt;= 1; b &lt;&lt;= 1; };  unsigned result = 0; while (a &amp;&amp; msb) { if (b &lt;= a) { a -= b; result |= msb; } msb &gt;&gt;= 1; b &gt;&gt;= 1; }  return var ? result : a; }  int __divmod(int a, int b, int var) { unsigned sign = 0, asign = a &amp; (1&lt;&lt;31);  if (b == 0) return 0;  if (a &lt; 0) { sign ^= 1; a = -a; }  if (b &lt; 0) { sign ^= 1; b = -b; }  unsigned result = __udivmod(a, b, var);  if (var) return sign ? -result : result; else return asign ? -result : result; }  int __udivsi3(int a, int b) { return __udivmod(a, b, 1); }  int __umodsi3(int a, int b) { return __udivmod(a, b, 0); }  int __divsi3(int a, int b) { return __divmod(a, b, 1); }  int __modsi3(int a, int b) { return __divmod(a, b, 0); } <\/code><\/pre>\n<p> <\/div>\n<\/p><\/div>\n<p> \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0443 \u043d\u0430\u0441 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043f\u043e-\u0441\u0432\u043e\u0435\u043c\u0443, \u0434\u043b\u044f \u043b\u0438\u043d\u043a\u043e\u0432\u0449\u0438\u043a\u0430 \u0437\u0430\u0432\u043e\u0434\u0438\u043c \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433 core.ld. <\/p>\n<pre><code class=\"cpp\">MEMORY {     MEM (rwx) : ORIGIN = 0x00000000, LENGTH = 65536 \/\/ \u0437\u0434\u0435\u0441\u044c \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0435 \u0432\u044b\u043b\u0435\u0437\u0430\u0442\u044c \u0437\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 } SECTIONS {     .text :     {         _text = .;         *boot*.o(.text) \/\/ \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u0434 (\u0441\u0435\u043a\u0446\u0438\u044f text)         *(.text*)         _etext = .;     } &gt; MEM     .data :     {         _data = .;         *(.rodata*) \/\/ \u0437\u0430 \u043a\u043e\u0434\u043e\u043c \u043d\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435         *(.data*)         _global = . + 0x800;         *(.sbss*) \/\/ \u043f\u043e\u0442\u043e\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043d\u0443\u043b\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0435         *(.bss*)         *(.sdata*)         *(.*)         _edata = .;         . = ALIGN(4);     } &gt; MEM    PROVIDE ( _stack = ORIGIN(MEM) + LENGTH(MEM) ); \/\/\u0441\u0442\u0435\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u043d\u0446\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0440\u0430\u0441\u0442\u0451\u0442 \u0432\u043d\u0438\u0437, \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 } <\/code><\/pre>\n<p> \u0412\u0441\u0451 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0417\u0430\u0432\u043e\u0434\u0438\u043c \u0431\u0430\u0442\u043d\u0438\u043a, \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 (bin\\riscv-none-elf), \u043f\u043e\u0434 \u043a\u0430\u043a\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c (rv32e \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f embedded, ilp32e, elf32lriscv). \u0417\u0430\u0434\u0430\u0451\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 (PERFORMANCE_RUN \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f, ITERATIONS=1 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0430 \u0442\u0435\u0441\u0442\u0430, COMPILER_FLAGS \u043a\u0430\u043a\u0438\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u043b\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0441\u0442\u0438), \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0432\u0438\u043c O2. \u0418 \u0432\u0430\u0436\u043d\u044b\u0439 \u043f\u0443\u043d\u043a\u0442, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0444\u043b\u0430\u0433 -ffreestanding, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u043b memmove \u0432\u0435\u0437\u0434\u0435 \u0433\u0434\u0435 \u043d\u0438 \u043f\u043e\u043f\u0430\u0434\u044f (\u0434\u0430\u0436\u0435 \u0432 memmove, \u0434\u0430 \u0433\u0434\u0435 \u043b\u043e\u0433\u0438\u043a\u0430 \u0442\u043e). <\/p>\n<pre><code class=\"bash\">set gcc_bin=..\\xpack-riscv-none-elf-gcc-12.2.0-3\\bin\\riscv-none-elf set arch=rv32e set abi=ilp32e  set COMPILER_FLAGS=\\\"compiler_flags\\\" set ccflags=-march=%arch% -mabi=%abi% -ffreestanding -I \".\/src\" -O2 -DPERFORMANCE_RUN=1 -DITERATIONS=1 -DCOMPILER_FLAGS=%COMPILER_FLAGS%  set ldflags=-Tcore.ld -Map coremark.map -m elf32lriscv <\/code><\/pre>\n<p> \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. <\/p>\n<pre><code class=\"bash\">%gcc_bin%-gcc %ccflags% -c src\/core_list_join.c -o build\/core_list_join.o <\/code><\/pre>\n<p> \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430\u0432\u0430\u043b\u0438\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u043c\u043e\u0436\u043d\u043e \u0438\u0445 \u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0440\u0435\u0448\u0438\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043d\u0435 \u0441 CoreMark, \u0430 \u0441 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0443\u0447\u0442\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e exe&#8217;\u0448\u043d\u0438\u043a, \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. <\/p>\n<pre><code class=\"bash\">%gcc_bin%-ld %ldflags% -o coremark.o build\/boot.o build\/core_list_join.o build\/core_main.o ... <\/code><\/pre>\n<p> \u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u0441\u0438\u043c\u0443\u043b\u044f\u0442\u043e\u0440 \u043d\u0443\u0436\u0435\u043d \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0431\u0430\u0439\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442 (\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, ALIGN(4) \u0432 core.ld \u0431\u044b\u043b\u043e \u043d\u0430\u0434\u043e \u0434\u043b\u044f \u0440\u043e\u0432\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e objcopy \u043c\u043e\u0433 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0435 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 4). <\/p>\n<pre><code class=\"bash\">%gcc_bin%-objcopy -O binary --reverse-bytes=4 coremark.o coremark.bin <\/code><\/pre>\n<p> \u0415\u0449\u0451 \u0435\u0441\u0442\u044c \u0441\u043c\u044b\u0441\u043b \u0432\u044b\u0434\u0430\u0442\u044c \u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430, \u0442\u0430\u043c \u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u043e\u043c\u0430\u043d\u0434 \u0435\u0441\u0442\u044c \u0441 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438, \u0438 \u043d\u043e\u043c\u0435\u0440\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432, \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435. \u041d\u043e \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. <\/p>\n<pre><code class=\"bash\">%gcc_bin%-objdump -D -S coremark.o &gt; coremark.S %gcc_bin%-gcc %ccflags% -fverbose-asm -S src\/core_state.c -o build\/core_state.s <\/code><\/pre>\n<p> \u041f\u043e\u0442\u043e\u043c \u043f\u0440\u0438 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u0442\u044c \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433. <\/p>\n<pre><code class=\"cpp\">Disassembly of section .text:  00000000 &lt;_start&gt;:        0:00010117          auipcsp,0x10        4:00010113          mvsp,sp        8:00005197          auipcgp,0x5        c:93418193          addigp,gp,-1740 # 493c &lt;_global&gt;       10:179000ef          jalra,988 &lt;main&gt; ... <\/code><\/pre>\n<p> \u0421\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u0431\u0430\u0442\u043d\u0438\u043a. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">make.bat<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"bash\">set gcc_bin=..\\xpack-riscv-none-elf-gcc-12.2.0-3\\bin\\riscv-none-elf set arch=rv32e set abi=ilp32e  set COMPILER_FLAGS=\\\"compiler_flags\\\" set ccflags=-march=%arch% -mabi=%abi% -ffreestanding -I \".\/src\" -O2 -DPERFORMANCE_RUN=1 -DITERATIONS=1 -DCOMPILER_FLAGS=%COMPILER_FLAGS%  set ldflags=-Tcore.ld -Map coremark.map -m elf32lriscv  rmdir \/q \/s build del \/q coremark.hex del \/q coremark.bin del \/q coremark.map del \/q coremark.o del \/q coremark.S mkdir build  %gcc_bin%-gcc %ccflags% -c src\/core_list_join.c -o build\/core_list_join.o %gcc_bin%-gcc %ccflags% -c src\/core_main.c -o build\/core_main.o %gcc_bin%-gcc %ccflags% -c src\/core_matrix.c -o build\/core_matrix.o %gcc_bin%-gcc %ccflags% -c src\/core_state.c -o build\/core_state.o %gcc_bin%-gcc %ccflags% -c src\/core_util.c -o build\/core_util.o %gcc_bin%-gcc %ccflags% -c src\/core_portme.c -o build\/core_portme.o %gcc_bin%-gcc %ccflags% -c src\/ee_printf.c -o build\/ee_printf.o %gcc_bin%-gcc %ccflags% -c mylib.c -o build\/mylib.o %gcc_bin%-gcc %ccflags% -c boot.s -o build\/boot.o  %gcc_bin%-gcc %ccflags% -fverbose-asm -S src\/core_state.c -o build\/core_state.s %gcc_bin%-gcc %ccflags% -fverbose-asm -S src\/core_list_join.c -o build\/core_list_join.s %gcc_bin%-gcc %ccflags% -fverbose-asm -S mylib.c -o build\/mylib.s  %gcc_bin%-ld %ldflags% -o coremark.o build\/boot.o build\/core_list_join.o build\/core_main.o build\/core_matrix.o build\/core_state.o build\/core_util.o build\/core_portme.o build\/ee_printf.o build\/mylib.o  %gcc_bin%-objdump -D -S coremark.o &gt; coremark.S %gcc_bin%-objcopy -O binary --reverse-bytes=4 coremark.o coremark.bin  pause <\/code><\/pre>\n<p> <\/div>\n<\/p><\/div>\n<p> \u0411\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0433\u043e\u0442\u043e\u0432, \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0431\u0435\u0440\u0451\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c.<\/p>\n<h2>\u041e\u0431\u0432\u044f\u0437\u043a\u0430 \u044f\u0434\u0440\u0430<\/h2>\n<p> \u0412\u0441\u044e \u043e\u0431\u0432\u044f\u0437\u043a\u0443 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432 \u043e\u0434\u043d\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u044f\u0434\u0440\u0430. <\/p>\n<pre><code class=\"vhdl\">RiscVCore core0 ( .clock(clock), .reset(reset),  .instruction_address(i_addr), .instruction_data(i_data),  .data_address(d_addr), .data_width(d_width), .data_in(d_data_in), .data_out(d_data_out), .data_read(data_r), .data_write(data_w) ); <\/code><\/pre>\n<p> \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0442\u0430\u043a\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0434\u043b\u044f \u0441\u0438\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432 \u043a\u043e\u0434\u0435. <\/p>\n<pre><code class=\"vhdl\">reg clock = 0; initial while(1) #1 clock = !clock; <\/code><\/pre>\n<p> \u0414\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443, \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u0432\u0441\u0451 \u0441\u0431\u0440\u043e\u0441\u0438\u043b\u043e\u0441\u044c. <\/p>\n<pre><code class=\"vhdl\">reg reset = 1; reg [1:0] reset_counter = 2;  always@(posedge clock) begin reset_counter &lt;= reset_counter == 0 ? 0 : reset_counter - 1; reset &lt;= reset_counter != 0; end <\/code><\/pre>\n<p> \u0415\u0449\u0451 \u0438\u0437 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438 \u043d\u0430\u0434\u043e \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u0439. <\/p>\n<pre><code class=\"vhdl\">reg [31:0] timer; reg [31:0] timer_divider;  always@(posedge clock) begin if(reset) begin timer = 0; timer_divider = 0; end else begin if (timer_divider == 100) begin timer &lt;= timer + 1; timer_divider &lt;= 0; end else begin timer_divider &lt;= timer_divider + 1; end end end <\/code><\/pre>\n<p> \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u043d\u0435\u0451 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443. \u041f\u043e\u043a\u0430 \u043d\u0435\u0442 \u043a\u044d\u0448\u0430 \u0438 \u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e, \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0430\u043c\u044f\u0442\u044c \u043b\u0435\u0436\u0438\u0442 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435. <\/p>\n<pre><code class=\"vhdl\">`define MEMORY_SIZE (2**16\/4) reg [31:0] rom [0:`MEMORY_SIZE-1];  begin $dumpfile(\"core_tb.vcd\"); \/\/\u0444\u0430\u0439\u043b \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 $dumpvars(); \/\/\u0438 \u0432 \u043d\u0451\u043c \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u0430\u043a\u0438\u0435 \u0435\u0441\u0442\u044c for (i = 0; i &lt; `MEMORY_SIZE; i = i + 1) \/\/\u043f\u0430\u043c\u044f\u0442\u044c \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u0437\u0430\u043d\u0443\u043b\u044f\u0435\u043c, \u0447\u0442\u043e\u0431\u044b bss \u0441\u0435\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0431\u044b\u043b\u0430 \u0447\u0438\u0441\u0442\u043e\u0439 rom[i] = 32'b0; fdesc = $fopen(\"code.bin\", \"rb\"); \/\/\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u0448\u043d\u0438\u043a fres = $fread(rom, fdesc, 0, `MEMORY_SIZE); \/\/\u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e \u0432 \u043f\u0430\u043c\u044f\u0442\u044c $fclose(fdesc); #3000000 \/\/\u0436\u0434\u0451\u043c 3\u043a\u043a \u0446\u0438\u043a\u043b\u043e\u0432 (\u0443 \u043d\u0430\u0441 \u0446\u0438\u043a\u043b - \u044d\u0442\u043e 1 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u0430) $finish(); \/\/\u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e end <\/code><\/pre>\n<p> \u041a \u043f\u0430\u043c\u044f\u0442\u0438 \u0438\u0434\u0451\u0442 \u043a\u0443\u0447\u0430 \u043f\u0440\u043e\u0432\u043e\u0434\u043a\u043e\u0432, \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f, \u0447\u0442\u043e \u043a\u0443\u0434\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c. <\/p>\n<pre><code class=\"vhdl\">wire [31:0] i_addr; wire [31:0] i_data; wire [31:0] d_addr; wire [31:0] d_data_in; wire [31:0] d_data_out; wire data_r; wire data_w; wire [1:0] d_width; \/\/0-byte, 1-half, 2-word <\/code><\/pre>\n<p> \u041f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u0445\u043f\u043e\u0440\u0442\u043e\u0432\u0430\u044f. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f FPGA \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043e\u0431\u0435 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443, \u0430 \u0447\u0438\u0442\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u043d\u044b\u0445.<br \/> \u0414\u043b\u044f \u0448\u0438\u043d\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432\u0441\u0451 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e: \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0434\u0440\u0435\u0441, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412\u0441\u0451 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u044b\u0440\u043e\u0432\u043d\u0435\u043d. \u0425\u043e\u0442\u044f \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0436\u0430\u0442\u044b\u043c\u0438 16-\u0431\u0438\u0442\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438, \u043d\u043e \u043f\u043e\u043a\u0430 \u0438\u0445 \u043d\u0435\u0442, \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043b\u0430\u0431\u0438\u0442\u044c\u0441\u044f. <\/p>\n<pre><code class=\"vhdl\">assign i_data = rom[i_addr[31:2]]; <\/code><\/pre>\n<p> \u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. ROM \u0441\u043e\u0431\u0440\u0430\u043d \u043f\u043e 4 \u0431\u0430\u0439\u0442\u0430, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043a\u0430\u043a-\u0442\u043e \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e. <\/p>\n<pre><code class=\"vhdl\">wire [31:0] old_data = rom[d_addr[31:2]]; wire [1:0] addr_tail = d_addr[1:0]; \/\/\u043e\u0442\u0441\u0442\u0443\u043f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043b\u043e\u0432\u0430 <\/code><\/pre>\n<p> \u0415\u0441\u043b\u0438 \u0431\u044b\u043b\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0447\u0442\u0435\u043d\u0438\u044f, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u0443\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0442\u043e \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u044f\u0434\u0440\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0430\u043c\u043e \u0432\u044b\u0440\u043e\u0432\u043d\u044f\u0435\u0442\u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043a \u043d\u0430\u0434\u043e. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0444\u043b\u0430\u0433 data_r, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u0448\u0438\u043d\u0443 \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0448\u0438\u043d\u0430 \u0443 \u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432 \u043e\u0434\u043d\u043e \u043c\u0435\u0441\u0442\u043e, \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u0438 \u043d\u0435\u0442. \u0415\u0449\u0451 \u043f\u043e\u0434\u0441\u0443\u043d\u0435\u043c \u0432 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0435\u043a\u0441\u043e\u0440 \u0442\u0430\u0439\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430. <\/p>\n<pre><code class=\"vhdl\">assign d_data_in = d_addr == 32'h40000008 ? timer : d_addr &lt; `MEMORY_SIZE * 4 ? (old_data &gt;&gt; (addr_tail * 8)) : 0; <\/code><\/pre>\n<p> \u0417\u0430\u043f\u0438\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0431\u0430\u0439\u0442\u044b \u043d\u0430\u0434\u043e \u043c\u0435\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043d\u0435\u0442. <\/p>\n<pre><code class=\"vhdl\">assign byte_mask = d_width == 0 ? 4'b0001 &lt;&lt; addr_tail :                    d_width == 1 ? 4'b0011 &lt;&lt; addr_tail :                                   4'b1111; <\/code><\/pre>\n<p> \u0414\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0438\u0441\u043b\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u043c, \u043d\u0430\u0434\u043e \u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0434\u043e \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442\u0430, \u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c. \u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 2 \u0431\u0430\u0439\u0442\u0430, \u0430 \u0441\u0434\u0432\u0438\u0433 \u043d\u0430 3 \u0431\u0430\u0439\u0442\u0430 (\u044d\u0442\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043b\u0435\u0437\u0442\u044c \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b). \u041f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043a\u0438\u043d\u0443\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u043e \u043d\u0435\u0432\u044b\u0440\u043e\u0432\u043d\u0435\u043d\u043d\u043e\u0435 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435. <\/p>\n<pre><code class=\"vhdl\">wire [31:0] aligned_out = d_data_out &lt;&lt; addr_tail * 8;  always@(posedge clock) begin if (data_w) begin rom[d_addr[31:2]] &lt;= {byte_mask[3] ? aligned_out[31:24] : old_data[31:24], byte_mask[2] ? aligned_out[23:16] : old_data[23:16], byte_mask[1] ? aligned_out[15:8] : old_data[15:8], byte_mask[0] ? aligned_out[7:0] : old_data[7:0]}; end end <\/code><\/pre>\n<p> \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0438 \u0435\u0449\u0451 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0430\u043c\u044f\u0442\u0438, \u044d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435. <\/p>\n<pre><code class=\"vhdl\">always@(posedge clock) begin if (data_w &amp;&amp; d_addr == 32'h40000004) begin \/\/\u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 $write(\"%c\", d_data_out); end else if (data_r &amp;&amp; d_addr == 32'h40000008) begin ; \/\/\u0442\u0430\u0439\u043c\u0435\u0440 \u0447\u0438\u0442\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e end else if ((data_r || data_w) &amp;&amp; (d_addr &lt; 8'hff || d_addr &gt; `MEMORY_SIZE * 4)) begin \/\/\u043d\u0443\u043b\u0435\u0432\u044b\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044e \u0440\u0430\u0431\u043e\u0442\u044b $finish(); end end <\/code><\/pre>\n<p> \u0421\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0451 \u0432 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">core_tb.v<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"vhdl\">`timescale 1ns \/ 1ns  module core_tb;  `define MEMORY_SIZE (2**16\/4)  reg clock = 0; reg reset = 1; reg [1:0] reset_counter = 2; reg [31:0] rom [0:`MEMORY_SIZE-1]; \/\/\u043f\u0430\u043c\u044f\u0442\u044c wire [31:0] i_addr; wire [31:0] i_data; wire [31:0] d_addr; wire [31:0] d_data_in; wire [31:0] d_data_out; wire data_r; wire data_w; wire [1:0] d_width; \/\/0-byte, 1-half, 2-word wire [3:0] byte_mask;  reg [31:0] timer; reg [31:0] timer_divider;  integer i, fdesc, fres; initial while(1) #1 clock = !clock; initial begin $dumpfile(\"core_tb.vcd\"); $dumpvars(); for (i = 0; i &lt; `MEMORY_SIZE; i = i + 1) rom[i] = 32'b0; \/\/$readmemh(\"code.hex\", rom); fdesc = $fopen(\"code.bin\", \"rb\"); fres = $fread(rom, fdesc, 0, `MEMORY_SIZE); $fclose(fdesc); #3000000 $finish(); end  always@(posedge clock) begin reset_counter &lt;= reset_counter == 0 ? 0 : reset_counter - 1; reset &lt;= reset_counter != 0; end  RiscVCore core0 ( .clock(clock), .reset(reset), \/\/.irq,  .instruction_address(i_addr), .instruction_data(i_data),  .data_address(d_addr), .data_width(d_width), .data_in(d_data_in), .data_out(d_data_out), .data_read(data_r), .data_write(data_w) );  \/\/\u0448\u0438\u043d\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0440\u043e\u0432\u043d\u0435\u043d\u0430 assign i_data = rom[i_addr[31:2]];  \/\/\u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \/\/\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0432\u044b\u0440\u043e\u0432\u043d\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f, \u0442\u043e\u0447\u043d\u0435\u0435 \u0432\u044b\u0440\u043e\u0432\u043d\u0435\u043d\u043d\u044b\u0439 \u043f\u043e \u0431\u0430\u0439\u0442\u0430\u043c wire [31:0] old_data = rom[d_addr[31:2]]; wire [1:0] addr_tail = d_addr[1:0];  \/\/\u0432\u0435\u0448\u0430\u0435\u043c \u043d\u0430 \u043e\u0431\u0449\u0443\u044e \u0448\u0438\u043d\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0438 \u043f\u0430\u043c\u044f\u0442\u044c assign d_data_in = d_addr == 32'h40000008 ? timer : d_addr &lt; `MEMORY_SIZE * 4 ? (old_data &gt;&gt; (addr_tail * 8)) : 0; \/\/TODO data_read \u043d\u0435 \u043d\u0443\u0436\u0435\u043d?  \/\/\u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0430\u0441\u043a\u0430 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u044f\u0434\u0440\u0435, \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 assign byte_mask = d_width == 0 ? 4'b0001 &lt;&lt; addr_tail :                    d_width == 1 ? 4'b0011 &lt;&lt; addr_tail :                                   4'b1111;  \/\/\u0440\u0430\u0437 \u0434\u043b\u044f \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u0441\u0434\u0432\u0438\u0433 \/\/\u0442\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0441\u043b\u043e\u0432 \u0434\u0435\u0448\u0435\u0432\u043b\u0435 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0430 \u0434\u0432\u0430 \u0431\u0430\u0439\u0442\u0430 \/\/TODO \u043d\u0443\u0436\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0441\u043b\u043e\u0432\u0430? wire [31:0] aligned_out = d_data_out &lt;&lt; addr_tail * 8;  always@(posedge clock) begin if (data_w) begin rom[d_addr[31:2]] &lt;= {byte_mask[3] ? aligned_out[31:24] : old_data[31:24], byte_mask[2] ? aligned_out[23:16] : old_data[23:16], byte_mask[1] ? aligned_out[15:8] : old_data[15:8], byte_mask[0] ? aligned_out[7:0] : old_data[7:0]}; end if (data_w &amp;&amp; d_addr == 32'h4000_0004) begin \/\/\u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 $write(\"%c\", d_data_out); end else if (data_r &amp;&amp; d_addr == 32'h40000008) begin ; \/\/\u0442\u0430\u0439\u043c\u0435\u0440 \u0447\u0438\u0442\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e end else if ((data_r || data_w) &amp;&amp; (d_addr &lt; 8'hff || d_addr &gt; `MEMORY_SIZE * 4)) begin \/\/\u043d\u0443\u043b\u0435\u0432\u044b\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044e \u0440\u0430\u0431\u043e\u0442\u044b $finish(); end  if(reset) begin timer = 0; timer_divider = 0; end else begin if (timer_divider == 100) begin timer &lt;= timer + 1; timer_divider &lt;= 0; end else begin timer_divider &lt;= timer_divider + 1; end end end endmodule <\/code><\/pre>\n<p> <\/div>\n<\/p><\/div>\n<p> \u0423\u0440\u0430, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c. \u0410 \u0433\u0434\u0435?<\/p>\n<h2>\u0421\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044f<\/h2>\n<p> \u0414\u043b\u044f \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/bleyer.org\/icarus\/\" rel=\"nofollow noopener noreferrer\">icarus verilog<\/a>. \u0417\u0430\u043f\u0443\u0441\u043a \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u0432\u0430 \u044d\u0442\u0430\u043f\u0430. <\/p>\n<pre><code class=\"bash\">::\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043a\u0430\u0440\u0443\u0441\u0430 \"..\\iverilog\\bin\\iverilog.exe\" -I ..\/core -o tmp_sim core_tb.v ..\/core\/core.v  ::\u0441\u0438\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c \"..\\iverilog\\bin\\vvp.exe\" tmp_sim <\/code><\/pre>\n<p> \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0442\u0435\u0441\u0442 \u0432\u044b\u0434\u0430\u0451\u0442 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443. \u041a\u0430\u043a \u0435\u0451 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043d\u043e \u0435\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, 100\/\u0447\u0438\u0441\u043b\u043e \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u0430\u0441\u0442 \u0447\u0438\u0441\u043b\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430 \u043a\u043b\u043e\u043a.<\/p>\n<p> <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/kn\/lb\/ju\/knlbjuxbvx6tbs8rw-693zu9huo.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/kn\/lb\/ju\/knlbjuxbvx6tbs8rw-693zu9huo.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/kn\/lb\/ju\/knlbjuxbvx6tbs8rw-693zu9huo.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<p> \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0437\u0430\u0434\u0430\u043d \u0432 \u0444\u0430\u0439\u043b\u0435 \u043e\u0431\u0432\u044f\u0437\u043a\u0438. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 Gtk Wave, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0434\u0451\u0442 \u0432 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0435 \u0441 \u0438\u043a\u0430\u0440\u0443\u0441\u043e\u043c. <\/p>\n<pre><code class=\"bash\">::\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 call \"..\\iverilog\\gtkwave\\bin\\gtkwave.exe\" core_tb.vcd <\/code><\/pre>\n<p> \u0422\u0430\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0438 \u0432\u0441\u0451 \u043f\u0440\u043e\u0447\u0435\u0435.<\/p>\n<p> <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/gp\/mx\/fs\/gpmxfsve1779deyyvowqjonaigs.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/gp\/mx\/fs\/gpmxfsve1779deyyvowqjonaigs.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/gp\/mx\/fs\/gpmxfsve1779deyyvowqjonaigs.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<p> \u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u043e\u043c, \u0437\u043d\u0430\u0447\u0438\u0442 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u043f\u043e\u0434\u0445\u0432\u0430\u0442\u0438\u043b\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e. \u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u043a\u043e\u043f\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438. \u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0442\u0435\u0441\u0442 \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u043d\u0430 60%.<\/p>\n<p> <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/bb\/ho\/jk\/bbhojkiczs4k4gfue1awai8o9yo.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/bb\/ho\/jk\/bbhojkiczs4k4gfue1awai8o9yo.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/bb\/ho\/jk\/bbhojkiczs4k4gfue1awai8o9yo.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<p> \u0415\u0449\u0451 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u0430\u0436\u0434\u0430\u044f \u0447\u0435\u0442\u0432\u0451\u0440\u0442\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0431\u044b\u043b\u0430 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c.<\/p>\n<p> <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/qi\/jn\/76\/qijn76t9iesyqmoqcuapee82-rm.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/qi\/jn\/76\/qijn76t9iesyqmoqcuapee82-rm.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/qi\/jn\/76\/qijn76t9iesyqmoqcuapee82-rm.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<p> \u0412 \u043e\u0431\u0449\u0435\u043c, \u0442\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u0442\u044c \u043f\u0430\u0440\u043e\u0432\u043e\u0437\u0438\u043a, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043a\u0430\u0442\u0430\u0442\u044c\u0441\u044f \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u0442\u0430\u043a \u0447\u0442\u043e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f. \u041b\u0443\u0447\u0448\u0435 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u0440\u0430\u0441\u0442\u0435\u0442.<\/p><\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/910440\/\"> https:\/\/habr.com\/ru\/articles\/910440\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/qq\/ea\/92\/qqea92hmnawa34pzq8yvmon9id0.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/qq\/ea\/92\/qqea92hmnawa34pzq8yvmon9id0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/qq\/ea\/92\/qqea92hmnawa34pzq8yvmon9id0.png 781w\" loading=\"lazy\" decode=\"async\"\/><br \/> \u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/909700\/\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u044f\u0434\u0440\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c. \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0443\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e. \u0415\u0449\u0451 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-460094","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/460094","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=460094"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/460094\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=460094"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=460094"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=460094"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}