Skip to content

Commit

Permalink
use readmemb where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
trun committed Apr 21, 2015
1 parent 42c1765 commit ff9c2b9
Show file tree
Hide file tree
Showing 9 changed files with 639 additions and 30 deletions.
Binary file added data/boot.bin
Binary file not shown.
4 changes: 4 additions & 0 deletions data/hexascii.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
30 31 32 33
34 35 36 37
38 39 41 42
43 44 45 46
16 changes: 0 additions & 16 deletions data/hexascii.rom

This file was deleted.

5 changes: 5 additions & 0 deletions data/jump.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
40 00
48 00
50 00
58 00
60 00
10 changes: 0 additions & 10 deletions data/jump.rom

This file was deleted.

6 changes: 3 additions & 3 deletions src/gb/mmu.v
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
`default_nettype none
`timescale 1ns / 1ps

module memory_controller(
module mmu(
input wire clock,
input wire reset,

Expand Down Expand Up @@ -59,8 +59,8 @@ module memory_controller(
reg [7:0] jump_rom [0:9];

initial begin
$readmemh("data/boot.rom", boot_rom, 0, 255);
$readmemh("data/jump.rom", jump_rom, 0, 9);
$readmemb("data/boot.bin", boot_rom, 0, 255);
$readmemh("data/jump.hex", jump_rom, 0, 9);
end

// High RAM
Expand Down
2 changes: 1 addition & 1 deletion src/io/debug/cls_spi.v
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ module cls_spi(
reg [1:0] data_idx;

initial begin
$readmemh("data/hexascii.rom", glyph_rom, 0, 15);
$readmemh("data/hexascii.hex", glyph_rom, 0, 15);
end

always @(posedge clock) begin
Expand Down
310 changes: 310 additions & 0 deletions src/top/s6atlys.ucf

Large diffs are not rendered by default.

316 changes: 316 additions & 0 deletions src/top/s6atlys.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
`default_nettype none
`timescale 1ns / 1ps

// Main board module.
module s6atlys(
// Global clock
input wire CLK_100M,

// onboard HDMI OUT
//output wire HDMIOUTCLKP,
//output wire HDMIOUTCLKN,
//output wire HDMIOUTD0P,
//output wire HDMIOUTD0N,
//output wire HDMIOUTD1P,
//output wire HDMIOUTD1N,
//output wire HDMIOUTD2P,
//output wire HDMIOUTD2N,
//output wire HDMIOUTSCL,
//output wire HDMIOUTSDA,

// LEDs
output wire [7:0] LED,

// Switches
input wire [7:0] SW,

// Buttons
input wire [5:0] BTN,

// PMOD Connector
inout wire [7:0] JB
);

//
// Initialize outputs -- remove these when they're actually used
//

// Audio output
//assign AUD_L = 0;
//assign AUD_R = 0;

// VGA output
//assign VGA_R = 0;
//assign VGA_G = 0;
//assign VGA_B = 0;
//assign VGA_HSYNC = 0;
//assign VGA_VSYNC = 0;

//
// Clocks (GameBoy clock runs at ~4.194304 MHz)
//
// FPGABoy runs at 33.33 MHz, mostly to simplify the video controller.
// Certain cycle sensitive modules, such as the CPU and Timer are
// internally clocked down to the GameBoy's normal speed.
//

// Core Clock: 33.33 MHz
wire coreclk, core_clock;
DCM_SP core_clock_dcm (.CLKIN(CLK_100M), .CLKFX(coreclk), .RST(1'b0));
defparam core_clock_dcm.CLKFX_DIVIDE = 6;
defparam core_clock_dcm.CLKFX_MULTIPLY = 2;
defparam core_clock_dcm.CLKDV_DIVIDE = 3.0;
defparam core_clock_dcm.CLKIN_PERIOD = 10.000;
BUFG core_clock_buf (.I(coreclk), .O(core_clock));

// Initial Reset
wire reset_init, reset;
SRL16 reset_sr(.D(1'b0), .CLK(core_clock), .Q(reset_init),
.A0(1'b1), .A1(1'b1), .A2(1'b1), .A3(1'b1));

// HDMI Clocks
// TODO: No idea what these look like yet.

// Joypad Clock: 1 KHz
wire pulse_1khz;
reg clock_1khz;
divider#(.DELAY(33333)) div_1ms (
.reset(reset_init),
.clock(core_clock),
.enable(pulse_1khz)
);

// CLS Clock: 200 Khz
wire pulse_200khz;
reg clock_200khz;
divider#(.DELAY(166)) div_5us (
.reset(reset_init),
.clock(core_clock),
.enable(pulse_200khz)
);

//
// CPU clock - overflows every 8 cycles
//

reg [2:0] clock_divider;

wire cpu_clock;
BUFG cpu_clock_buf(.I(clock_divider[2]), .O(cpu_clock));

//
// Switches
//
// SW0-SW4 - Breakpoints Switches (Not Implemented)
// SW5 - Step Clock
// SW6 - Step Enable
// SW7 - Power (Reset)
//

wire reset_sync, step_sync, step_enable;
debounce debounce_step_sync(reset_init, core_clock, SW[5], step_sync);
debounce debounce_step_enable(reset_init, core_clock, SW[6], step_enable);
debounce debounce_reset_sync(reset_init, core_clock, !SW[7], reset_sync);

assign reset = (reset_init || reset_sync);

// Game Clock
wire clock;
BUFGMUX clock_mux(.S(step_enable), .O(clock),
.I0(core_clock), .I1(step_sync));

//
// Buttons
//
// BTN0 - Not Implemented
// BTN1 - Joypad
// BTN2 - PC SP
// BTN3 - AF BC
// BTN4 - DE HL
//

reg [1:0] mode;
wire mode0_sync, mode1_sync, mode2_sync, mode3_sync;
debounce debounce_mode0_sync(reset_init, core_clock, BTN[2], mode0_sync);
debounce debounce_mode1_sync(reset_init, core_clock, BTN[3], mode1_sync);
debounce debounce_mode2_sync(reset_init, core_clock, BTN[4], mode2_sync);
debounce debounce_mode3_sync(reset_init, core_clock, BTN[1], mode3_sync);

//
// GameBoy
//

// GB <-> Cartridge + WRAM
wire [15:0] A;
wire [7:0] Di;
wire [7:0] Do;
wire wr_n, rd_n, cs_n;

// GB <-> VRAM
wire [15:0] A_vram;
wire [7:0] Di_vram;
wire [7:0] Do_vram;
wire wr_vram_n, rd_vram_n, cs_vram_n;

// GB <-> Display Adapter
wire [1:0] pixel_data;
wire pixel_clock;
wire pixel_latch;
wire hsync, vsync;

// GB <-> Joypad Adapter
wire [3:0] joypad_data;
wire [1:0] joypad_sel;

// GB <-> Audio Adapter
wire audio_left, audio_right;

// GB <-> CLS SPI
wire [15:0] PC;
wire [15:0] SP;
wire [15:0] AF;
wire [15:0] BC;
wire [15:0] DE;
wire [15:0] HL;
wire [15:0] A_cpu;
wire [7:0] Di_cpu;
wire [7:0] Do_cpu;

gameboy gameboy (
.clock(clock),
.cpu_clock(cpu_clock),
.reset(reset),
.reset_init(reset_init),
.A(A),
.Di(Di),
.Do(Do),
.wr_n(wr_n),
.rd_n(rd_n),
.cs_n(cs_n),
.A_vram(A_vram),
.Di_vram(Di_vram),
.Do_vram(Do_vram),
.wr_vram_n(wr_vram_n),
.rd_vram_n(rd_vram_n),
.cs_vram_n(cs_vram_n),
.pixel_data(pixel_data),
.pixel_clock(pixel_clock),
.pixel_latch(pixel_latch),
.hsync(hsync),
.vsync(vsync),
.joypad_data(joypad_data),
.joypad_sel(joypad_sel),
.audio_left(audio_left),
.audio_right(audio_right),
// debug output
.dbg_led(LED),
.PC(PC),
.SP(SP),
.AF(AF),
.BC(BC),
.DE(DE),
.HL(HL),
.A_cpu(A_cpu),
.Di_cpu(Di_cpu),
.Do_cpu(Do_cpu)
);

// Internal ROMs and RAMs
reg [7:0] tetris_rom [0:32767];

initial begin
$readmemb("data/tetris.bin", tetris_rom, 0, 32767);
end

wire [7:0] Di_wram;

// WRAM
async_mem #(.asz(8), .depth(8192)) wram (
.rd_data(Di_wram),
.wr_clk(clock),
.wr_data(Do),
.wr_cs(!cs_n && !wr_n),
.addr(A),
.rd_cs(!cs_n && !rd_n)
);

// VRAM
async_mem #(.asz(8), .depth(8192)) vram (
.rd_data(Di_vram),
.wr_clk(clock),
.wr_data(Do_vram),
.wr_cs(!cs_vram_n && !wr_vram_n),
.addr(A_vram),
.rd_cs(!cs_vram_n && !rd_vram_n)
);

assign Di = A[14] ? Di_wram : tetris_rom[A];

// Joypad Adapter
wire [15:0] joypad_state;
joypad_snes_adapter joypad_adapter(
.clock(clock_1khz),
.reset(reset),
.button_sel(joypad_sel),
.button_data(joypad_data),
.button_state(joypad_state),
.controller_data(JB[4]),
.controller_clock(JB[5]),
.controller_latch(JB[6])
);

cls_spi cls_spi(
.clock(clock_200khz),
.reset(reset),
.mode(mode),
.ss(JB[0]),
.mosi(JB[1]),
.miso(JB[2]),
.sclk(JB[3]),
.A(A_cpu),
.Di(Di_cpu),
.Do(Do_cpu),
.PC(PC),
.SP(SP),
.AF(AF),
.BC(BC),
.DE(DE),
.HL(HL),
.joypad_state(joypad_state)
);

// driver for divider clocks and debug elements
always @(posedge core_clock) begin
if (reset_init) begin
clock_1khz <= 1'b0;
clock_200khz <= 1'b0;
mode <= 2'b0;
end else begin
if (pulse_1khz)
clock_1khz <= !clock_1khz;
if (pulse_200khz)
clock_200khz <= !clock_200khz;

if (mode0_sync)
mode <= 2'b00;
else if (mode1_sync)
mode <= 2'b01;
else if (mode2_sync)
mode <= 2'b10;
else if (mode3_sync)
mode <= 2'b11;
end
end

always @(posedge clock) begin
if (reset_init) begin
clock_divider <= 1'b0;
end else begin
if (step_enable)
clock_divider <= clock_divider + 4;
else
clock_divider <= clock_divider + 1;
end
end

endmodule

0 comments on commit ff9c2b9

Please sign in to comment.