From: Joshua Wise <joshua@rebirth.joshuawise.com> Date: Sat, 29 Mar 2008 05:36:50 +0000 (-0400) Subject: Initial X-Git-Url: http://git.joshuawise.com/fpgaboy.git/commitdiff_plain/2f55f80959676970f85a02a9a968668ae2113dda Initial --- 2f55f80959676970f85a02a9a968668ae2113dda diff --git a/CPUDCM.xaw b/CPUDCM.xaw new file mode 100644 index 0000000..f28ae93 --- /dev/null +++ b/CPUDCM.xaw @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.4e +$92x6a=(`fgn#ga|htc,twimmj~x#k~ha.DSCDDhq&I[YIMB.yct5>6339$;8<5>8:35#mE709;0>;5=0/2347=5=81?86:!910815><0'934;>74:;-6l1<I[IC[DT>7:CQS_YHFESTOL]LAEKMCZEKC820M_YU_NLO]ZEKC@DTIUZJROCO50=FZ^PTCCBV_BNHMKYQIE_N=o5NRVX\KKJ^WMIFS^YFTBJJJBYDDB;;7L\XZ^MMH\YCL[UH<<>4ASUY[JHKQVNO^RM>109BVR\XGGFRSIJ]_BNH53=FZ^PTCCBV_EFQ[CJNXOFD\<;4ASUY[JHKQVLISHV[ESLBH44<I[]QSB@CY^KMWQYI]Do0M_YU_NLO]ZVJKM;>7L\XZ^MMH\YUMZO_SAAHIB3;?DTPRVEE@TQYAMKG[A@TWDEOIl5NSRM@[ROS@o1J[WQLLJ@VBQ_WM8;87LYU_BNH[JSSX\^TXT^Jc:CT^Z@KG^^R\H64AVX\TDTSl2K\VR]VNUJWKJJ33KE_D95MUGE7?FJL8?1H@F?7079@HN408<1H@F<W8:AOO7^609?0OAE6049@HNBQk2IGGIXPDHTJ@@3<KEAMN85LLJD[<>EKCOR:4=74CMIE\ZDRNo1H@FHW_CWECZOI[]i0OAEIX^FJRLBBm2IGGKVPMTNWMUJ^12IGGKVPOTV6?FJLAG;:7NBDIO]GMSOCMVHRS?l4CMIJJZOE]OM:<6MCKHL\MGSAOVCE_Yh4CMIJJZOE]OMTCXZ7;BNHMKYNFj1H@FGA_QGQMJBb3JF@ECQ\RB]W]UC6:2IGGB[[_QJBW@YT@@L_o6MCK^DFAADFKB30OBCBIUVF@2=DZLK_II84DBO\WUd<LJGT_]QFNRVg?ACTCL]TMIDZSU31?A@TWOXN]XKACX]NKAC6:2NG@RH]EPWFJF_XEFNN96J\SDL21>BR\PUHUNBJ_BMQV@ESAFD<7IQYAMWF<>C_\LXEMAo4F@AWKW_XBO?0JLB\E89EFZUH][IN56HFN^WMMQU?3OE^XR][R`9EKPRX]GC__l5IOTV\RDJRM;1MT<5F5:KAQCA692@BXYK]_HLSQQYSQYOh7GG[TDP\TN4WCj1AEYZJR^TBHPC13EEHGHJn;MM@O@BXG\^87AAX3:OK^2=JW_KGYH94NDVTKWM33GEEI<5@8:ME@ATDXLh0\EO\E^QKMCR>3YCEDL]MURc8TLHN[NDOII64PHLTMARO02ZYE@ZVPD33?UTHXVZBBD]NCUKUA0=W[JF@:6^\DNLF0>VTMG20\^GACEG@7>TT\k1XEJKWTDPMEI0<[@DL@Hm4SUCQPPVX_HC_:6][AUWP57=TQZ^NAR]VNBJQKKIR[:1_C]:4TSWF<>STMVH^JJ74URG\FP@@[<1]EHY>b:ZBSZPBZZCDB<j4XHNJJ]+_LK*;"<.\TT@#4+7'IZIBE>5WSU48\adXAm;;7Ujb_LcikwPbzzcdb<>4Xeo\Ilhhz_oydaa5:Y3>5[23R:1;P:4asuy7>bdek1}i}foo"2*52<~angj6vl3r734`+2nn99<pNOp3g8DE~72O096<u\3d84f?1c2899:;m::01gf6}i?>0:7c97:59'33<0<2wX?i48b;5g>455>?i>6<:?cc9g3g<7280:w^=j:6`93a<6;;<=o84>3e`0?sR0:3:1=7?56zQ0a?1e2>n1=><96b7956be;2h=i7>50;192~"c2>i0(<k57d9'5c<0n2.9<79:;%50>f=e<90;6<=50;2x 34=;o1/i7<6;%d92d=#9809?6*>2;00?!742;>0(<:5229'50<2l2.::78n;%34>6=#910>n6*>9;6:?!7f2;;0(>m55c9'6d<23-9;6:5+308;?!532=30(>756:&0e?203-9i68l4$5392a=#<?087):=:458 15==>1/8849f:&7<?2<,=k19o5+4c86<>"3l3?37):j:c9'17<3k2.>5764$4g95>"1j3>27)9?:638 46=i2.:h7:i;%77>7=#=:027d=<:18'24<012.=?78i;:k1f?6=,?;1;45+6185b>"1;3<m76g98;29 37=?01/:=49f:9j23<72-<:6:74$7292c=<a?=1<7*91;5:?!072?l07d8;:18'24<012.=<78i;:k70?6=,?;1;45+6185b>=h::0;6)8>:6;8?j4?290/:<489:9l61<72-<:6:74;n06>5<#>80<565`2883>!062>307b<9:18'24<0121d>:4?:%42>2?<3f8h6=4+6084=>"1;3<m7)?l:308?j4c290/:<489:9l2f<72-<:6:o4$4d92c=<g<?1<7*91;5:?!042?l07b8::18'24<0121vn>850;094?6|,?819<5f5183>!062>30(;=56g98k0e=83.==796;%40>3`<3th9j7>52;294~"1:3897d;?:18'24<012.=?78i;:m6g?6=,?;1;45+6285b>=z{:?1<7<t=52976=:;?0>o6*>b;14?xu5m3:1>v3;0;0`?84a2<:0q~;9:1828272<?0(;755b9~w6>=83;p1>85519'2<<282wx??4?:0y>6c<2k2.=57;l;|q03?6=8r.=57;l;|m67<728qvb?=50;3xyk43290:wp`=5;295~{i:?0;6<urn3594?7|utwvLMMt2d8f=2160><vLMLt0|BCT~{GH \ No newline at end of file diff --git a/FPGABoy.ise b/FPGABoy.ise new file mode 100644 index 0000000..5e643e3 Binary files /dev/null and b/FPGABoy.ise differ diff --git a/GBZ80Core.v b/GBZ80Core.v new file mode 100644 index 0000000..9bc60a8 --- /dev/null +++ b/GBZ80Core.v @@ -0,0 +1,169 @@ +`define REG_A 0 +`define REG_B 1 +`define REG_C 2 +`define REG_D 3 +`define REG_E 4 +`define REG_F 5 +`define REG_H 6 +`define REG_L 7 +`define REG_SPH 8 +`define REG_SPL 9 +`define REG_PCH 10 +`define REG_PCL 11 + +`define FLAG_Z 8'b10000000 +`define FLAG_N 8'b01000000 +`define FLAG_H 8'b00100000 +`define FLAG_C 8'b00010000 + +`define STATE_FETCH 2'h0 +`define STATE_DECODE 2'h1 +`define STATE_EXECUTE 2'h2 +`define STATE_WRITEBACK 2'h3 + +`define INSN_LD_reg_imm8 8'b00xxx110 +`define INSN_imm8_reg_A 3'b111 +`define INSN_imm8_reg_B 3'b000 +`define INSN_imm8_reg_C 3'b001 +`define INSN_imm8_reg_D 3'b010 +`define INSN_imm8_reg_E 3'b011 +`define INSN_imm8_reg_H 3'b100 +`define INSN_imm8_reg_L 3'b101 +`define INSN_imm8_reg_dHL 3'b110 + +module GBZ80Core( + input clk, + output reg [15:0] busaddress, /* BUS_* is latched on STATE_FETCH. */ + inout [7:0] busdata, + output reg buswr, output reg busrd); + + reg [1:0] state = 0; /* State within this bus cycle (see STATE_*). */ + reg [2:0] cycle = 0; /* Cycle for instructions. */ + + reg [7:0] registers[11:0]; + + reg [15:0] address; /* Address for the next bus operation. */ + + reg [7:0] opcode; /* Opcode from the current machine cycle. */ + + reg [7:0] rdata, wdata; /* Read data from this bus cycle, or write data for the next. */ + reg rd = 1, wr = 0, newcycle = 1; + + reg [7:0] buswdata; + assign busdata = buswr ? buswdata : 8'bzzzzzzzz; + + initial begin + registers[ 0] = 0; + registers[ 1] = 0; + registers[ 2] = 0; + registers[ 3] = 0; + registers[ 4] = 0; + registers[ 5] = 0; + registers[ 6] = 0; + registers[ 7] = 0; + registers[ 8] = 0; + registers[ 9] = 0; + registers[10] = 0; + registers[11] = 0; + end + + always @(posedge clk) + case (state) + `STATE_FETCH: begin + if (wr) + buswdata <= wdata; + if (newcycle) + busaddress <= {registers[`REG_PCH], registers[`REG_PCL]}; + else + busaddress <= address; + buswr <= wr; + busrd <= rd; + state <= `STATE_DECODE; + end + `STATE_DECODE: begin + if (newcycle) begin + opcode <= busdata; + rdata <= busdata; + cycle <= 0; + end else + if (rd) rdata <= busdata; + buswr <= 0; + busrd <= 0; + state <= `STATE_EXECUTE; + end + `STATE_EXECUTE: begin +`define EXEC_INC_PC \ + {registers[`REG_PCH], registers[`REG_PCL]} <= {registers[`REG_PCH], registers[`REG_PCL]} + 1 +`define EXEC_NEXTADDR_PCINC \ + address <= {registers[`REG_PCH], registers[`REG_PCL]} + 1 +`define EXEC_NEWCYCLE \ + newcycle <= 1; rd <= 1; wr <= 0 + casex (opcode) + `INSN_LD_reg_imm8: begin + case (cycle) + 0: begin + `EXEC_INC_PC; + `EXEC_NEXTADDR_PCINC; + newcycle <= 0; + rd <= 1; + end + 1: begin + `EXEC_INC_PC; + if (opcode[5:3] == `INSN_imm8_reg_dHL) begin + address <= {registers[`REG_H], registers[`REG_L]}; + wdata <= rdata; + rd <= 0; + wr <= 1; + end else begin + `EXEC_NEWCYCLE; + end + end + 2: begin + `EXEC_NEWCYCLE; + end + endcase + end + endcase + state <= `STATE_WRITEBACK; + end + `STATE_WRITEBACK: begin + casex (opcode) + `INSN_LD_reg_imm8: + case (cycle) + 0: cycle <= 1; + 1: case (opcode[5:3]) + `INSN_imm8_reg_A: begin registers[`REG_A] <= rdata; cycle <= 0; end + `INSN_imm8_reg_B: begin registers[`REG_B] <= rdata; cycle <= 0; end + `INSN_imm8_reg_C: begin registers[`REG_C] <= rdata; cycle <= 0; end + `INSN_imm8_reg_D: begin registers[`REG_D] <= rdata; cycle <= 0; end + `INSN_imm8_reg_E: begin registers[`REG_E] <= rdata; cycle <= 0; end + `INSN_imm8_reg_H: begin registers[`REG_H] <= rdata; cycle <= 0; end + `INSN_imm8_reg_L: begin registers[`REG_L] <= rdata; cycle <= 0; end + `INSN_imm8_reg_dHL: cycle <= 2; + endcase + 2: cycle <= 0; + endcase + endcase + state <= `STATE_FETCH; + end + endcase +endmodule + +`timescale 1ns / 1ps +module TestBench(); + reg clk = 0; + wire [15:0] addr; + wire [7:0] data; + wire wr, rd; + reg [7:0] rom [2047:0]; + + initial $readmemh("rom.hex", rom); + always #10 clk <= ~clk; + GBZ80Core core( + .clk(clk), + .busaddress(addr), + .busdata(data), + .buswr(wr), + .busrd(rd)); + assign data = rd ? rom[addr] : 8'bzzzzzzzz; +endmodule diff --git a/rom.hex b/rom.hex new file mode 100644 index 0000000..61c700d --- /dev/null +++ b/rom.hex @@ -0,0 +1,12 @@ +// LD (HL), 05h +36 +05 +// LD H, 12h +26 +12 +// LD L, 34h +2E +34 +// LD (HL), 56h +36 +56