17æ¥ç®: [x86] CPU (IA-32) ãFPGAã§è£½ä½
ãã®è¨äºã¯ã²ã¨ãã§CPUã¨ã¨ãã¥ã¬ã¼ã¿ã¨ã³ã³ãã¤ã©ãä½ã Advent Calendar 2017ã®17æ¥ç®ã®è¨äºã§ãã
ã¡ããã©1é±éåã« åç´ãªCPUãFPGAã§ä½ã£ãã
ããã¦æ¨æ¥ã¯ x86ã®ã¨ãã¥ã¬ã¼ã¿ãå®æãããã
ãã®2ã¤ãçµã¿åããã¦ãFPGAä¸ã§åãx86ã®CPUãä½ããã ããããæ¬ä¸¸ã«åãè¾¼ããï¼ï¼ï¼
x86ãHDLã§è¨è¿°ããæ¥æ¬èªæ¸ç±ã解説è¨äºã¯ããã¾ã®ã¨ããåå¨ããªãã¨æãã å é£ãåã£ãã
ä»æ§
å ¨å½ä»¤ãå®è£ ããã®ã¯å¤§å¤ãªã®ã§ã以ä¸ã®è¡¨ã®èµ¤ãå½ä»¤ã«ãã¼ããã
ãããã®å½ä»¤ããããã°ãå帰å¼åºãã§ãã£ããããæ°ãè¨ç®ã§ããã
åºæ¬æ¦ç¥
è² æ ã軽æ¸ããããã åä½CPU ãæ¹è¯ããæ©è½ã追å ããå½¢ã§å®è£ ãããã¨æãã
åä½CPUã®å½ä»¤ã»ããã¯ãã®è¨äºã«æ¸ããã ããã¤ã¨x86ã®ç¸éç¹ãã¾ã¨ããã¨
解説é | åä½CPU | ããããä½ãx86å½ä»¤ã»ããã®CPU |
---|---|---|
1 | ã¬ã¸ã¹ã¿ã8bitããã©ã°ã¯ã¼ããã©ã°ã®ã¿ | ã¬ã¸ã¹ã¿ã32bitããã©ã°ã¯4ç¨®é¡ |
2 | ã¯ããã¯æ¯ã«å ¨ã¡ã¢ãªãèªã | å¿ è¦ãªé¨åã ãèªã |
3 | æ©æ¢°èªã®ä¸ä½4bbitã§ãªãã©ã³ããæå® | ModRMã§ãªãã©ã³ããæå® |
4 | å
¨ã¦ã®æ¼ç®å¦çãalways_comb å
ã§å®è¡ |
æ¼ç®å¦çãåã¢ã¸ã¥ã¼ã«ã«åé¢ |
5 | æ¡ä»¶ä»ãã¸ã£ã³ãå½ä»¤ã¯jz ã ã |
ãã©ã°ãå¢ããã®ã§ãæ¡ä»¶ä»ãã¸ã£ã³ãå½ä»¤ãå¢ãã |
6 | é¢æ°å¼åºã¯æªãµãã¼ããebp ã¬ã¸ã¹ã¿ã¯ç¡ã |
ebp ã¬ã¸ã¹ã¿ãåå¨ããcall , leave , ret ã®3å½ä»¤ãå«ã |
7 | å ¨æ¼ç®ãç°¡åã«ã¤ããã | ModRMã®å ¥ã£ãæ¼ç®ãããã©ã |
ç¸éç¹ãä¸å¿ã«ãä»ããã½ã¼ã¹ã³ã¼ãã解説ãã¦ããã
1. ã¬ã¸ã¹ã¿ã¨ãã©ã°ã®æ¡å¼µ
ã¬ã¸ã¹ã¿ã®32bitåã¨ãã©ã°ã®æ¡å¼µã¯ç°¡åã ã åä½CPUã®7ã ã£ãã¤ã³ããã¯ã¹ã31ã«å¤ããã ãã§æ¸ãã ãã®å¦ç㯠top.svã®æåã®æ¹ ã§è¡ã£ã¦ããã
// ã¬ã¸ã¹ã¿ã®å®£è¨ logic [31:0] eax; // FF // ecx, edx, ebx, esp, ebp, esi, ediãç¥ logic [31:0] eip; // FF logic cf, zf, sf, of; // wire // ã¬ã¸ã¹ã¿ç´åã®ã¯ã¤ã¤ã®å®£è¨ logic [31:0] next_eax; // wire // ecx, edx, ebx, esp, ebp, esi, ediãç¥ logic [31:0] next_eip; // wire logic next_cf, next_zf, next_sf, next_of;
2. ã¡ã¢ãªãã§ããã®æ¹å
CPUã§æ¼ç®ãè¡ãããã
ã¤ã¾ãã¯ããã¯ã®ç«ã¡ä¸ããã§ã¬ã¸ã¹ã¿eax
ãä¸æ¸ããããã
ãã®ããã«ã¯ãæ´æ°ç¨ã®ã¯ã¤ã¤next_eax
ã®é»å§ãä½ãçµã¿åããåè·¯ãå¿
è¦ã ã£ãã
ãã®çµã¿åããåè·¯ã¯ãåä½CPUãä»ä½ã®x86ãmake_next_reg
ã¨ããã¢ã¸ã¥ã¼ã«åã§çµ±ä¸ããã
ååã¯ããã¤ã«ã¡ã¢ãªå
¨ä½ã渡ãã¦ããã
ååCPUãä½ã£ãã¨ãã®è¨äº
ã®ä¸ã®æ¹ã«æ¸ãããããã¾ãã«ã²ã©ãå¦çã ã£ãã
ã¡ã¢ãªãã§ããå¦çãæ¹åããmake_next_reg
ã«æ¸¡ãã¡ã¢ãªã®ãµã¤ãºãå°ãããããã
ãã®ããã«ã¯
top.sv
ã®ä¸ã§ãªãã³ã¼ãã®ã¯ã¤ã¤ãä½ã£ã¦
// ãªãã³ã¼ãã®ã¯ã¤ã¤ãä½æ logic [7:0] opecode; assign opecode = memory[eip];
make_next_reg
ã®å¼æ°ã«å
¥ãã¦
渡ãã°è¯ãã
make_next_reg make_next_reg_0( // ç¥ , opecode, imm8, imm32 , mod, r, m, r_reg, m_reg // ç¥ , eax, ecx, edx // ç¥ , next_eax, next_ecx, next_edx // ç¥ );/*}}}*/
ããã§ã¯opecode
以å¤ã«ãå³å¤ããã¬ã¸ã¹ã¿ããè²ã
渡ãã¦ããã
ååã¯opecode
ã渡ã代ããã«memory
ã渡ãã¦ãããã¨ãã§ããªããã¨ã ã
3. ModRMã§ãªãã©ã³ããæå®
opecode
ãmake_next_reg
ã«æ¸¡ããã¡ã¢ãªãã§ãããæ¹åãããã¨ãã§ããã
ãããã¡ã¢ãªãã§ããã¯opecode
ã¨å³å¤ã ãã§ã¯ãªããModRMãèæ
®ããªããã°ãªããªãã
ModRM
ã¯ãããããã®ã§ãmake_next_reg
ã«æ¸¡ãåã«å¤æ°ã®ã¯ã¤ã¤ãä½æããå¿
è¦ãããã
ãã®ãããã¾ã
top.sv
ã®ä¸ã§ModRMé¢é£ã®ã¯ã¤ã¤ãä¸æã«å®£è¨
ããã
ããããmake_modrm
ã¢ã¸ã¥ã¼ã«ã«æ¸¡ããã¨ã§ãModRMã«é¢ããé»å§å¤ãå¾ã¦ããã
logic [ 1:0] mod; logic [ 2:0] r; logic [ 2:0] m; logic [31:0] r_reg; logic [31:0] m_reg; logic [31:0] m_reg_plus_imm8 ; // M+imm8 logic [31:0] m_reg_plus_imm32; // M+imm32 logic [ 7:0] around_eip [6:0]; assign around_eip[0] = memory[eip+0]; assign around_eip[1] = memory[eip+1]; assign around_eip[2] = memory[eip+2]; assign around_eip[3] = memory[eip+3]; assign around_eip[4] = memory[eip+4]; assign around_eip[5] = memory[eip+5]; make_modrm make_modrm_0( around_eip, eax, ecx, edx, ebx, esp, ebp, esi, edi, // ç¥ mod, r, m, r_reg, m_reg, m_reg_plus_imm8, m_reg_plus_imm32 );
mod
ã¨r
ã¨m
ã¯åããã ããã
r_reg
ã¯3bitã®r
ã§æå®ãããã¬ã¸ã¹ã¿ã®åºå£é»å§ã表ãã¦ãããm_reg
ãåæ§ã
m_reg_plus_imm8
ã¯m_reg
ã«1byteã®å³å¤imm8
ã足ãããã®ã ã
ModRMã®çµ¡ãã å½ä»¤ã§ã¯ãadd [m_reg+imm8], R
ã®ããã«m_reg+imm8
ãé »åºããã®ã§ããããããä½ã£ã¦ãããã
ãããã®ã¯ã¤ã¤ã®é»å§å¤ããeip
å¨è¾ºã®ã¡ã¢ãªã®å¤around_eip
ãå
ã«ä½æããã¢ã¸ã¥ã¼ã«ãmake_modrm
ã§ããã
make_modrm
ã¢ã¸ã¥ã¼ã«ã®å®è£
ãè¦ã¦ã¿ãã¨
module make_modrm ( // ç¥ ); logic [7:0] modrm; assign modrm = memory_eip[1]; assign mod = modrm[7:6]; assign r = modrm[5:3]; assign m = modrm[2:0]; // ç¥ // always_combå ã§ã¯ãã¢ã¸ã¥ã¼ã«ã®outputã«ç´æ¥æ¥ç¶ã§ããªãã // ãªã®ã§ã¯ã¤ã¤ã® end_r_reg ã宣è¨ã㦠r_reg ã«ãã¾ã logic [31:0] end_r_reg; assign r_reg = end_r_reg; // ç¥ // end_r_reg ã«ç·ãã¤ãªã always_comb begin case(r) 3'b000: end_r_reg = eax; 3'b001: end_r_reg = ecx; // 以ä¸ãedx, ebx, esp, ebp, esi, ediãåæ§ã«å¦ç endcase //ç¥ end endmodule
ç°¡åã®ããã«çç¥æ¹å¤ãã¦è¨è¼ããã
ãã®ã³ã¼ãã¯ãModRMã®3bitã®Rã«å¯¾å¿ããã¬ã¸ã¹ã¿ãåå¾ããã¯ã¤ã¤ã®r_reg
ã«ç¹ãã¢ã¸ã¥ã¼ã«ã ã¨æã£ã¦ã»ããã
å¦çã追ãã¨
- å
¥åã®
modrm
ãããåºåã®mod
ã¨r
ã¨m
ãåãåºã - ã¯ã¤ã¤ã®
end_r_reg
ã宣è¨ããr_reg
ã®å ¥åã«ã¤ãªã - caseæã使ãããã®ã§ã
always_comb
ã®ä¸ã§end_r_reg
ã®å ¥å£ã«ç·ãã¤ãªã
ãã¡ããr_reg
以å¤ã«ã(m_reg
ãªã©)ä½æãã¹ãé»å§å¤ã¯ããã
å®éã®make_modrm
ã¢ã¸ã¥ã¼ã«ã®ä¸ã§ã¯ããããã®å¿
è¦ãªé»å§å¤ãå
¨ã¦ä½æãã¦ããã
4. æ¼ç®å¦çãåã¢ã¸ã¥ã¼ã«ã«åé¢
ååä½ã£ãCPUã®make_next_reg
ã¢ã¸ã¥ã¼ã«ã§ã¯ãalways_comb
ã®ä¸ã§ãªãã³ã¼ãã«ããå ´ååããè¡ã£ã¦ããã
System Verilogã®ä»æ§ä¸ãalways
ã®ä¸ã§ã¯ã¢ã¸ã¥ã¼ã«ãå¼ã³åºããªãã®ã§ãå¿
è¦ãªæ¼ç®å¦çãå
¨ã¦always_comb
ä¸ã«ã¹ãæ¸ãããå¿
è¦ããã£ãã
ããã«ãä¸æ ¼å¥½ã ã
ä»åã¯ã¹ãã¼ãã«ããããå½ä»¤æ¯ã«ã¢ã¸ã¥ã¼ã«ã«åå²ããã
æ¨æ¥ã®x86ã¨ãã¥ã¬ã¼ã¿è£½ä½ãæãåºãã¦ã»ããã ããã§ã¯ãæ¼ç®å¦çã®æ§é ä½ãä½ããé åã«ãã¦ãæ·»åããªãã³ã¼ãã«ãããã¨ãããã¯ããã¯ã使ã£ã¦ããã
ããã¨åæ§ã«
ãæ¼ç®å¦çã®ã¯ã¤ã¤ãä½ããé
åã«ãã¦ãæ·»åããªãã³ã¼ãã«ãããã¨ãããã¯ããã¯ã使ãã°ãalways_comb
å
ã®caseæã使ããã¨ãªãåå²ãããã¨ãå¯è½ã«ãªãã
ã¤ã¾ã
- ã¯ããã¯æ¯ã«å ¨ç¨®é¡ã®æ¼ç®ãè¡ã
- çµæããæ¼ç®å¦çã®ã¯ã¤ã¤ã®é åãã«æ ¼ç´ãããæ·»åã¯è¨ç®ç¨®å¥ã«å¯¾å¿ãã1byteã®ãªãã³ã¼ãã«ãã
- ã¡ã¢ãªããåå¾ãããªãã³ã¼ãããã¨ã«ãã欲ããè¨ç®çµæã®ã¯ã¤ã¤ããå¾ã
- åå¾ããã¯ã¤ã¤ã®é»å§å¤ã§ã次åã¯ããã¯ç«ã¡ä¸ããã®ç¬éã«ã¬ã¸ã¹ã¿ãä¸æ¸ã
ãããããã¨ã§ãæ¼ç®å¦çã®ã¯ã¤ã¤ãä½ããé¨åãå½ä»¤æ¯ã«ã¢ã¸ã¥ã¼ã«åã§ãã¦ãå¯èªæ§ãåä¸ããã
説æãæ½è±¡çã§ãããã«ãããããããªããã³ã¼ããè¦ããã
make_next_reg.sv
ã®å
¨ä½åãè¦ãã¨
// opecode, eaxçããwrite_flag, next_eaxçãä½ãçµã¿åããåè·¯ module make_next_reg( output wire write_flag , output wire [31:0] write_addr , output wire [31:0] write_value // ç¥ , output wire [31:0] next_eax // ç¥ ); // next æ´æ°ç¨ã®å¤éã¯ã¤ã¤ãå®£è¨ logic end_write_flag[255:0]; logic [31:0] end_write_addr[255:0]; logic [31:0] end_write_value[255:0]; logic [31:0] end_eax [255:0]; // ç¥ // å¤éã¯ã¤ã¤ã®ãã¡ãopecodeã«åè´ãããã®ãnextã«ç¹ã assign write_flag = end_write_flag[opecode]; assign write_addr = end_write_addr[opecode]; assign write_value = end_write_value[opecode]; assign next_eax = end_eax[opecode]; // ç¥ // å ¨ç¨®é¡ã®è¨ç®ãå®è¡ãã¾ãã¯addã®çµæãend_***[01]ã«å ¥ãã inst_01_add_M_imm_R inst_01_add_M_imm_R_0( , mod, m, r_reg, m_reg // modRMé¢é£ã®ä»ã®å¼æ°ãç¥ , end_write_flag[8'h01], end_write_addr[8'h01], end_write_value[8'h01] , eax, ecx // ã¬ã¸ã¹ã¿é¢é£ã®å¼æ°ãç¥ , end_eax[8'h01], end_ecx[8'h01] // ã¬ã¸ã¹ã¿æ´æ°ç¨ã¯ã¤ã¤ã®å¼æ°ãç¥ ); // ç¥ (jmpãmovã®çµæããend_***[***]ã«å ¥ãã) endmodule
ãæ¼ç®å¦çã®ã¯ã¤ã¤ã®é
åãã¯end_eax [255:0]
ãªã©ã®ãend
ã§å§ã¾ãã¯ã¤ã¤é
åãæãã¦ããã
é
åãµã¤ãºã256ã«ããã®ã¯ããªãã³ã¼ãã0x00ãã0xffã¾ã§ã®256種é¡(1byte)ã ããã ã
5. æ¡ä»¶ä»ãã¸ã£ã³ãå½ä»¤
ãã£ãã®ã³ã¼ãã®æå¾ã§ãinst_01_add_M_imm_R
ã¨ããã¢ã¸ã¥ã¼ã«ããtlåºãã¦ããã
ããã¤ã¯add [M+imm], R
ã¨ããå½ä»¤ãå¦çããã¢ã¸ã¥ã¼ã«ãªã®ã ããModRMãå
¥ã£ã¦ãã¦ãããããã
詳細ã¯è¨äºã®æå¾ã«åããã
å¤ããã«
jcc imm32
ã®å½ä»¤ãå¦çããã¢ã¸ã¥ã¼ã«
ã®å®è£
ãè¦ã¦ã¿ãã
// jcc imm32 module inst_0f_jcc_imm32( input wire [31:0] imm8 , input wire [31:0] modrm_imm32 , output wire next_write_flag , output wire [31:0] next_write_addr , output wire [31:0] next_write_value , input reg [31:0] eax // input ecx, edx, ... , of ãç¥ , output wire [31:0] next_eax // output next_ecx, next_edx, ... , next_of ãç¥ ); // eip以å¤ã¯ååã®å¤ãä¿æ assign next_write_flag = 0; assign next_write_addr = 0; assign next_write_value = 0; assign next_eax = eax; // ecx, edx, ... , of ãåæ§ã«ååã®å¤ãä¿æãããç¥ logic [31:0] e_eip; assign next_eip = e_eip; logic [31:0] no_jump; assign no_jump = eip + 6; logic [31:0] jump; assign jump = eip + 6 + modrm_imm32; always_comb begin case(imm8) 8'h80: e_eip = (of == 1) ? jump : no_jump; 8'h81: e_eip = (of == 0) ? jump : no_jump; 8'h82: e_eip = (cf == 1) ? jump : no_jump; 8'h83: e_eip = (cf == 0) ? jump : no_jump; // ä»ã®æ¡ä»¶ä»ãã¸ã£ã³ãã¯ç¥ default: e_eip = no_jump; endcase end endmodule
jmp imm32
ã®æ©æ¢°èªå½ä»¤ã復ç¿ãããã
ä¾ãã°ã¡ã¢ãªã¢ãã¬ã¹ 0x12345678 ã«æ¡ä»¶ä»ãã¸ã£ã³ãããå½ä»¤ã ã¨
ã¢ãã¬ã¹ | eip |
no_jump |
|||||
---|---|---|---|---|---|---|---|
åå | opecode |
imm8 |
modrm_imm32[3] |
[2] |
[1] |
[0] |
|
ä¸èº« | 0f | 80ãã8fã®é | 78 | 56 | 34 | 12 | 次ã®å½ä»¤ |
ãã®imm8
ã®å¤ã«å¿ãã¦ãã¸ã£ã³ãã®æ¡ä»¶å¼(a>b
ãa<b
ã)ãå®ã¾ã£ã¦ããã
ãããå®ç¾ããããã«
- ã¡ã¢ãªã«ã¯ä½ãæ¸ãè¾¼ã¾ãªã
eax
,ecx
çã®ã¬ã¸ã¹ã¿ãååã®å¤ãä¿æ- ãã©ã°ãå¤æ´ããªã
- ããã°ã©ã ã«ã¦ã³ã¿
eip
ããimm8
ã¨ãã©ã°ãæ¯è¼ãã¦æ¸ãæãã
ã¨ããå¦çãè¡ã£ã¦ããã
6. é¢æ°å¼åº
é¢æ°å¼åºã®è§£èª¬è¨äº
ãèªã¿è¿ãã¦ã»ããã®ã ããé¢æ°ãå¼ã¶ã«ã¯call
ãã¦leave
ãã¦ret
ããã°ããã£ãã
ãããã®å®è£ ãã¡ã¢ãã¦ããã
call
å®è£
ã¯ããã
ãã®å½ä»¤ã¯push
ã§ãcallã®æ¬¡ã®å½ä»¤ããã¹ã¿ãã¯ã«ç©ãã ãã¨ãjmp imm32
ããã®ã¨ç価ã ã£ãã
// moduleæãçç¥ assign next_write_flag = 1; assign next_write_addr = esp-4; assign next_write_value = eip+5; // callå½ä»¤ã®ä¸åä¸ã®eipãå ¥ãã assign next_esp = esp-4; assign next_ebp = ebp; assign next_eip = (eip+5) + imm32; // ä»ã®next_***ã¯ååã®å¤ãä¿æ
leave
å®è£
ã¯ããã
ãã®å½ä»¤ã¯mov esp, ebp
ãããã¨pop ebp
ããã®ã¨ç価ã ã£ãã
// moduleæãçç¥ // next_write_***ã¯ååã®å¤ãä¿æ assign next_esp = ebp+4; assign next_ebp = ebp_leave_value; assign next_eip = eip+1; // ä»ã®next_***ã¯ååã®å¤ãä¿æ
ret
å®è£
ã¯ããã
ãã®å½ä»¤ã¯pop eip
ã¨ç価ã ã£ãã
// moduleæãçç¥ // next_write_***ã¯ååã®å¤ãä¿æ assign next_esp = esp+4; assign next_ebp = ebp; assign next_eip = stack_value; // ä»ã®next_***ã¯ååã®å¤ãä¿æ
7. ModRMã®å ¥ã£ãæ¼ç®
æå¾ã«add [M+imm], R
å½ä»¤ãå¦çããã¢ã¸ã¥ã¼ã«inst_01_add_M_imm_R
ã説æããã
ä»æ¥ã®è¨äºã®ã4. æ¼ç®å¦çãåã¢ã¸ã¥ã¼ã«ã«åé¢ãã®ã¨ããã§åºã¦ããå½ä»¤ã ããã ãã¶ãããããã ModRMãå ¥ãã¨ããã©ãã®ã ã
inst_01_add_M_imm_R
ã®å®è£
ãè¦ã¦ã¿ãã¨
module inst_01_add_M_imm_R( input wire [ 1:0] mod // modRMã®mod (0,1,2,3) , input wire [ 2:0] m // modRMã®M (0~7) , input wire [31:0] r_reg // modRMã®Rã§æå®ãããã¬ã¸ã¹ã¿ã®åºå£ , input wire [31:0] m_reg // modRMã®Mã§æå®ãããã¬ã¸ã¹ã¿ã®åºå£ , input wire [31:0] m_reg_plus_imm8 // M+imm8ã®ã¡ã¢ãªã¢ãã¬ã¹ , input wire [31:0] m_reg_plus_imm32 // M+imm32ã®ã¡ã¢ãªã¢ãã¬ã¹ , input wire [31:0] memval_m_reg // [M] ã®ã¡ã¢ãªã®å¤ // modrmç³»ã®inputãç¥ , output wire next_write_flag // ã¡ã¢ãªã«æ¸ãè¾¼ãæã¯1, ãããªãã°0 , output wire [31:0] next_write_addr // ã¡ã¢ãªã«æ¸ãè¾¼ãã¢ãã¬ã¹ , output wire [31:0] next_write_value // ã¡ã¢ãªã«æ¸ãè¾¼ãå¤ , input reg [31:0] eax // eaxã¬ã¸ã¹ã¿ã®åºå£ // ã¬ã¸ã¹ã¿ç³»ã®inputãç¥ , output wire [31:0] next_eax // 次åã¯ããã¯ã®eaxã¬ã¸ã¹ã¿ã®å ¥å£ // æ´æ°ç¨ã¯ã¤ã¤ã®outputãç¥ ); // always_combå ã§ç´æ¥next_***ã«ç¹ããã¨ã¯ã§ããªãã®ã§ãe_***ããã¾ã logic e_write_flag; logic [31:0] e_write_addr; logic [31:0] e_write_value; logic [31:0] e_eax; // ç¥ assign next_write_flag = e_write_flag; assign next_write_addr = e_write_addr; assign next_write_value = e_write_value; assign next_eax = e_eax; // ç¥ // e_***ã«ç·ãç¹ãã§ãéæ¥çã«next_***ãæ¸ãæã always_comb begin case(mod[1:0]) // add [M], R ã®å¦ç 2'b00: begin e_write_flag = 1; // ã¡ã¢ãªã®æ¸ãè¾¼ã¿ãã©ã°ãç«ã¦ã e_write_addr = m_reg; // æ¸ãè¾¼ãã¢ãã¬ã¹ã¯ã¬ã¸ã¹ã¿Mã®å¤ãã®ãã® e_write_value = memval_m_reg + r_reg; // [M]=[M]+R e_eax = eax; // eax, ecx, ... ã¯ååã®å¤ãä¿æ e_ecx = ecx; // ç¥ e_edi = edi; // ããã°ã©ã ã«ã¦ã³ã¿ã®æ´æ° // ã¡ã¢ãªä¸ã®æ©æ¢°èªã¯ (HERE_ope) (ModRM) (NEXT_ope) ãªã®ã§+2ãã e_eip = eip+2; // ç¥ end // modã01, 10, 11ã®å¦çã¯ç¥ endcase end endmodule
æ··ä¹±ããå ´åã¯ãä»æ¥ã®è¨äºã®ã5. æ¡ä»¶ä»ãã¸ã£ã³ãå½ä»¤ãã®ã»ã¯ã·ã§ã³ãåèªãã¦æ¬²ããã
ãããã§ã¯e_eip
ã¨ããã¯ã¤ã¤ã宣è¨ããalways_comb
ä¸ã§ãã®é»å§å¤ãä½æãã¦ããã
ããã§åºã¦ããe_eip
ã¨å
¨ãåæ§ã«ãe_write_flag
ãe_eax
ã宣è¨ããalways_comb
ä¸ã§é»å§å¤ãæ´æ°ãã¦ããã
éè¦ãªã®ã¯always_comb
ã®ä¸èº«ã ããåé·ã«ãªãã®ã§ãmod=00
ã«è©²å½ããadd [M], R
ã®å¦çã ããè¼ããã
ãã®å ´å
e_write_flag = 1; // ã¡ã¢ãªã®æ¸ãè¾¼ã¿ãã©ã°ãç«ã¦ã e_write_addr = m_reg; // æ¸ãè¾¼ãã¢ãã¬ã¹ã¯ã¬ã¸ã¹ã¿Mã®å¤ãã®ãã® e_write_value = memval_m_reg + r_reg; // [M]=[M]+R
always_comb
ä¸ã§ãe_write_***
ã®ã¡ã¢ãªæ´æ°ç¨ã¯ã¤ã¤ã«é»å§å¤ãè¨å®ãããã¨ã§ãã¡ã¢ãªã«å¤ãæ¸ãè¾¼ãã§ããã
ã©ãã§ããã話
x86ã®CPUãFPGAä¸ã«å®è£ ããæ¹æ³ãæ¸ãããã©ãä¸åã®è¨äºã¨ãã¦ã¯åéãå¤ãããã¨æãã
ããããããªãã£ãå ´å㯠åä½CPUã®ä½æè¨(åå) (å¾å)ã ãèªã¿ç´ãã¦æ¬²ããã è¤éã«ãªã£ãã ãã§ãé£ãããªã£ãããã§ã¯ãªãã ModRMå¨ããé¤ãã°åä½CPUã¨å ¨ãå¤ãããªãã
ä»æ¥ã§CPUã®è©±é¡ã¯çµäºã ã x86ã®ã¨ãã¥ã¬ã¼ã¿ãä½ã£ãããFPGAã§å®è£ ããããä¸åºåãã¤ããã«ã¯ã¡ããã©ããã ææ¥ããã¯ã³ã³ãã¤ã©ã®èªä½ã ã 製ä½æã®è¨æ¶ãããªã失ããã¦ããã®ã§ãé å¼µããªãããªã