From e679a3ce689a452644a74df2debfedd25b2a08f2 Mon Sep 17 00:00:00 2001 From: Nicholas Orlowsky Date: Wed, 31 Jan 2024 20:57:11 -0600 Subject: [PATCH] code cleanup and font fix --- beeper.sv | 10 ++ chip8.sv | 54 +++++++++ cpu.sv | 301 ++++++++++++++++++++++++++++++++++++++++++++++++++ gpu.sv | 15 +++ keyboard.sv | 15 +++ makefile | 4 +- rng.sv | 19 ++++ rom_loader.sv | 12 +- yayacemu.cpp | 50 ++++----- yayacemu.sv | 65 ----------- 10 files changed, 443 insertions(+), 102 deletions(-) create mode 100644 beeper.sv create mode 100644 chip8.sv create mode 100644 cpu.sv create mode 100644 gpu.sv create mode 100644 keyboard.sv create mode 100644 rng.sv delete mode 100644 yayacemu.sv diff --git a/beeper.sv b/beeper.sv new file mode 100644 index 0000000..e88680f --- /dev/null +++ b/beeper.sv @@ -0,0 +1,10 @@ +module beeper ( + input wire [7:0] sound_timer + ); + + import "DPI-C" function void set_beep(bit beep); + + always_comb begin + set_beep(sound_timer > 0); + end +endmodule diff --git a/chip8.sv b/chip8.sv new file mode 100644 index 0000000..e0bcc98 --- /dev/null +++ b/chip8.sv @@ -0,0 +1,54 @@ +module chip8 ( + input wire clk_in + ); + + bit [31:0] vram [0:2047]; + bit [7:0] memory [0:4095]; + + bit keyboard [15:0]; + + bit [7:0] sound_timer; + bit [15:0] program_counter; + int cycle_counter; + + bit [7:0] random_number; + + + beeper beeper (sound_timer); + cpu cpu (memory, clk_in, keyboard, random_number, cycle_counter, program_counter, vram, sound_timer); + gpu gpu (vram); + keyboard kb (clk_in, keyboard); + rng randy (clk_in, program_counter, keyboard, cycle_counter, random_number); + rom_loader loader (memory); + + initial begin + bit [7:0] fontset [79:0] = { + 8'hF0, 8'h90, 8'h90, 8'h90, 8'hF0, // 0 + 8'h20, 8'h60, 8'h20, 8'h20, 8'h70, // 1 + 8'hF0, 8'h10, 8'hF0, 8'h80, 8'hF0, // 2 + 8'hF0, 8'h10, 8'hF0, 8'h10, 8'hF0, // 3 + 8'h90, 8'h90, 8'hF0, 8'h10, 8'h10, // 4 + 8'hF0, 8'h80, 8'hF0, 8'h10, 8'hF0, // 5 + 8'hF0, 8'h80, 8'hF0, 8'h90, 8'hF0, // 6 + 8'hF0, 8'h10, 8'h20, 8'h40, 8'h40, // 7 + 8'hF0, 8'h90, 8'hF0, 8'h90, 8'hF0, // 8 + 8'hF0, 8'h90, 8'hF0, 8'h10, 8'hF0, // 9 + 8'hF0, 8'h90, 8'hF0, 8'h90, 8'h90, // A + 8'hE0, 8'h90, 8'hE0, 8'h90, 8'hE0, // B + 8'hF0, 8'h80, 8'h80, 8'h80, 8'hF0, // C + 8'hE0, 8'h90, 8'h90, 8'h90, 8'hE0, // D + 8'hF0, 8'h80, 8'hF0, 8'h80, 8'hF0, // E + 8'hF0, 8'h80, 8'hF0, 8'h80, 8'h80 // F + }; + + // Load fontset into memory + for(int i = 0; i < 80; i++) begin + memory[i] = fontset[79-i]; + end + + // Initialize keyboard bits + for(int i = 0; i < 15; i++) begin + keyboard[i] = 0; + end + end +endmodule diff --git a/cpu.sv b/cpu.sv new file mode 100644 index 0000000..6a24591 --- /dev/null +++ b/cpu.sv @@ -0,0 +1,301 @@ +module cpu( + output bit [7:0] memory [0:4095], + input wire clk_in, + input wire keyboard [15:0], + input wire [7:0] random_number, + output int cycle_counter, + output wire [15:0] program_counter, + output wire [31:0] vram [0:2047], + output wire [7:0] sound_timer + ); + + bit halt; + int watch_key; + + logic [15:0] stack [0:15]; + logic [15:0] index_reg; + logic [3:0] stack_pointer; + logic [7:0] registers [0:15]; + logic [15:0] opcode; + logic [7:0] delay_timer; + + logic [15:0] scratch; + logic [15:0] scratch2; + + logic [7:0] scratch_8; + logic [7:0] scratch_82; + + logic [31:0] x_cord; + logic [31:0] y_cord; + logic [7:0] size; + logic [31:0] screen_pixel; + logic [7:0] sprite_pixel; + + // Initialize CPU + initial begin + halt = 0; + watch_key = 255; + sound_timer = 0; + delay_timer = 0; + cycle_counter = 0; + program_counter = 'h200; + stack_pointer = 4'b0000; + end + + always_ff @(posedge clk_in) begin + opcode = {memory[program_counter+0], memory[program_counter+1]}; + $display("HW : opcode is 0x%h (%b)", opcode, opcode); + $display("HW : PC %0d 0x%h", program_counter, program_counter); + + if (cycle_counter % 20 == 0) begin + if (delay_timer > 0) + delay_timer--; + if (sound_timer > 0) + sound_timer--; + end + + casez(opcode) + 'h00E0: begin + $display("HW : INSTR CLS"); + for(int i = 0; i < 2048; i++) begin + vram[i] = 0; + end + end + 'h00EE: begin + $display("HW : INSTR RET"); + stack_pointer--; + program_counter = stack[stack_pointer]; + end + 'h0???: $display("HW : INSTR SYS addr (Treating as NOP)"); + 'h1???: begin + $display("HW : INSTR JP addr"); + program_counter = (opcode & 'h0FFF) - 2; + end + 'h2???: begin + $display("HW : INSTR CALL addr"); + stack[stack_pointer] = program_counter; + stack_pointer++; + program_counter = (opcode & 'h0FFF) - 2; + end + 'h3???: begin + $display("HW : INSTR SE Vx, byte"); + scratch = (opcode & 'h00FF); + if (scratch[7:0] == registers[(opcode & 'h0F00) >> 8]) begin + program_counter += 2; + end + end + 'h4???: begin + $display("HW : INSTR SNE Vx, byte"); + scratch = (opcode & 'h00FF); + if (scratch[7:0] != registers[(opcode & 'h0F00) >> 8]) begin + program_counter += 2; + end + end + 'h5??0: begin + $display("HW : INSTR SE Vx, Vy"); + if (registers[(opcode & 'h00F0) >> 4] == registers[(opcode & 'h0F00) >> 8]) begin + program_counter += 2; + end + end + 'h6???: begin + $display("HW : INSTR LD Vx, byte"); + scratch = (opcode & 'h00FF); + registers[(opcode & 'h0F00) >> 8] = scratch[7:0]; + end + 'h7???: begin + $display("HW : INSTR ADD Vx, byte"); + scratch = (opcode & 'h00FF); + registers[(opcode & 'h0F00) >> 8] += scratch[7:0]; + end + 'h8??0: begin + $display("HW : INSTR LD Vx, Vy"); + registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4]; + end + 'h8??1: begin + $display("HW : INSTR OR Vx, Vy"); + registers[(opcode & 'h0F00) >> 8] |= registers[(opcode & 'h00F0) >> 4]; + registers[15] = 0; + end + 'h8??2: begin + $display("HW : INSTR AND Vx, Vy"); + registers[(opcode & 'h0F00) >> 8] &= registers[(opcode & 'h00F0) >> 4]; + registers[15] = 0; + end + 'h8??3: begin + $display("HW : INSTR XOR Vx, Vy"); + registers[(opcode & 'h0F00) >> 8] ^= registers[(opcode & 'h00F0) >> 4]; + registers[15] = 0; + end + 'h8??4: begin + $display("HW : INSTR ADD Vx, Vy"); + scratch_8 = registers[(opcode & 'h0F00) >> 8]; + registers[(opcode & 'h0F00) >> 8] += registers[(opcode & 'h00F0) >> 4]; + registers[15] = {7'b0000000, scratch_8 > registers[(opcode & 'h0F00) >> 8]}; + end + 'h8??5: begin + $display("HW : INSTR SUB Vx, Vy"); + scratch_8 = registers[(opcode & 'h0F00) >> 8]; + registers[(opcode & 'h0F00) >> 8] -= registers[(opcode & 'h00F0) >> 4]; + registers[15] = {7'b0000000, scratch_8 >= registers[(opcode & 'h0F00) >> 8]}; + end + 'h8??6: begin + $display("HW : INSTR SHR Vx {, Vy}"); + scratch_8 = registers[(opcode & 'h0F00) >> 8]; + registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4]>> 1; + registers[15] = {7'b0000000, ((scratch_8 & 8'h01) == 8'h01)}; + end + 'h8??7: begin + $display("HW : INSTR SUBN Vx, Vy"); + scratch_8 = registers[(opcode & 'h00F0) >> 4]; + scratch_82 = registers[(opcode & 'h0F00) >> 8]; + registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4] - registers[(opcode & 'h0F00) >> 8]; + registers[15] = {7'b0000000, (scratch_8 >= scratch_82)}; + end + 'h8??E: begin + $display("HW : INSTR SHL Vx {, Vy}"); + scratch_8 = registers[(opcode & 'h0F00) >> 8]; + registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4]<< 1; + + registers[15] = {7'b0000000, (scratch_8[7]) }; + end + 'h9??0: begin + $display("HW : INSTR SNE Vx, Vy"); + if (registers[(opcode & 'h00F0) >> 4] != registers[(opcode & 'h0F00) >> 8]) begin + program_counter += 2; + end + end + 'hA???: begin + $display("HW : INSTR LD I, addr"); + index_reg = (opcode & 'h0FFF); + end + 'hb???: begin + $display("HW : INSTR JP V0, addr"); + program_counter = {8'h00, registers[0]} + (opcode & 'h0FFF) - 2; + end + 'hc???: begin + $display("HW : RND Vx, addr"); + // TODO: use a real RNG module, this is not synthesizeable + scratch = {8'h00, random_number} % 16'h0100; + scratch2 = (opcode & 'h00FF); + registers[(opcode & 'h0F00) >> 8] = scratch[7:0] & scratch2[7:0]; + end + 'hD???: begin + $display("HW : INSTR DRW Vx, Vy, nibble"); + if (cycle_counter % 20 != 0) begin + halt = 1; + end else begin + halt = 0; + x_cord = {24'h000000, registers[(opcode & 'h0F00) >> 8]}; + y_cord = {24'h000000, registers[(opcode & 'h00F0) >> 4]}; + + x_cord %= 64; + y_cord %= 32; + + scratch = (opcode & 'h000F); + size = scratch[7:0]; + registers[15] = 0; + + for (int r = 0; r < size; r++) begin + for (int c = 0; c < 8; c++) begin + if (r + y_cord >= 32 || x_cord + c >= 64) + continue; + screen_pixel = vram[((r + y_cord) * 64) + (x_cord + c)]; + sprite_pixel = memory[{16'h0000, index_reg} + r] & ('h80 >> c); + + if (|sprite_pixel) begin + if (screen_pixel == 32'hFFFFFFFF) begin + registers[15] = 1; + end + vram[((r + y_cord) * 64) + (x_cord + c)] ^= 32'hFFFFFFFF; + end + end + end + end + end + 'hE?9E: begin + $display("HW : INSTR SKP Vx"); + if (keyboard[{registers[(opcode & 'h0F00) >> 8]}[3:0]] == 1) begin + program_counter += 2; + end + end + 'hE?A1: begin + $display("HW : INSTR SNE Vx"); + if (keyboard[{registers[(opcode & 'h0F00) >> 8]}[3:0]] != 1) begin + program_counter += 2; + end + end + 'hF?07: begin + $display("HW : INSTR LD Vx, DT"); + registers[(opcode & 'h0F00) >> 8] = delay_timer; + end + 'hF?0A: begin + $display("HW : INSTR LD Vx, K"); + halt = 1; + for(int i = 0; i < 16; i++) begin + if (watch_key == 255) begin + if (keyboard[i]) begin + watch_key = i; + end + end else begin + if (!keyboard[watch_key]) begin + halt = 0; + watch_key = 255; + end + end + end + end + 'hF?15: begin + $display("HW : INSTR LD DT, Vx"); + delay_timer = registers[(opcode & 'h0F00) >> 8]; + end + 'hF?18: begin + $display("HW : INSTR LD ST, Vx"); + sound_timer = registers[(opcode & 'h0F00) >> 8]; + end + 'hF?1E: begin + $display("HW : INSTR ADD I, Vx"); + index_reg = index_reg + {8'h00, registers[(opcode & 'h0F00) >> 8]}; + end + 'hF?29: begin + $display("HW : INSTR LDL F, Vx"); + index_reg = registers[(opcode & 'h0F00) >> 8] * 5; + end + 'hF?33: begin + $display("HW : INSTR LD B, Vx"); + scratch = {8'h00, registers[(opcode & 'h0F00) >> 8]}; + scratch2 = scratch % 10; + memory[index_reg + 2] = scratch2[7:0]; + scratch /= 10; + scratch2 = scratch % 10; + memory[index_reg + 1] = scratch2[7:0]; + scratch /= 10; + scratch2 = scratch % 10; + memory[index_reg + 0] = scratch2[7:0]; + end + 'hF?55: begin + $display("HW : INSTR LD [I], Vx"); + scratch = (opcode & 'h0F00) >> 8; + for (bit [7:0] i8 = 0; i8 <= scratch[7:0]; i8++) begin + scratch2 = index_reg + {8'h00, i8}; + memory[scratch2[11:0]] = registers[i8[3:0]]; + end + index_reg++; + end + 'hF?65: begin + $display("HW : INSTR LD Vx, [I]"); + scratch = (opcode & 'h0F00) >> 8; + for (bit [7:0] i8 = 0; i8 <= scratch[7:0]; i8++) begin + scratch2 = index_reg + {8'h00, i8}; + registers[i8[3:0]] = memory[scratch2[11:0]]; + end + index_reg++; + end + default: $display("HW : ILLEGAL INSTRUCTION"); + endcase + + if (!halt) + program_counter += 2; + + cycle_counter++; + end +endmodule diff --git a/gpu.sv b/gpu.sv new file mode 100644 index 0000000..045b3e2 --- /dev/null +++ b/gpu.sv @@ -0,0 +1,15 @@ +module gpu ( + input wire [31:0] vram [0:2047] + ); + + import "DPI-C" function void init_screen(); + import "DPI-C" function void draw_screen(logic [31:0] vram [0:2047]); + + initial begin + init_screen(); + end + + always_comb begin + draw_screen(vram); + end +endmodule diff --git a/keyboard.sv b/keyboard.sv new file mode 100644 index 0000000..4d80cea --- /dev/null +++ b/keyboard.sv @@ -0,0 +1,15 @@ +module keyboard ( + input wire clk_in, + output bit keyboard [15:0] + ); + + import "DPI-C" function bit [7:0] get_key(); + + always_ff @(posedge clk_in) begin + bit[7:0] keyval = get_key(); + if (&keyval != 1) begin + keyboard[keyval[3:0]] = keyval[7]; + end + end + +endmodule diff --git a/makefile b/makefile index c99007c..20a8f79 100644 --- a/makefile +++ b/makefile @@ -5,10 +5,10 @@ lint: verilator --lint-only --timing *.sv build: lint - verilator --cc --exe --build --timing -j 0 --top-module yayacemu *.sv yayacemu.cpp -CFLAGS "${SDL_CFLAGS}" -LDFLAGS "${SDL_LDFLAGS}" && clear + verilator --cc --exe --build --timing -j 0 --top-module chip8 *.sv yayacemu.cpp -CFLAGS "${SDL_CFLAGS}" -LDFLAGS "${SDL_LDFLAGS}" && clear run: build - obj_dir/Vyayacemu ${ROM_FILE} + obj_dir/Vchip8 ${ROM_FILE} clean: rm -rf obj_dir diff --git a/rng.sv b/rng.sv new file mode 100644 index 0000000..2a4963e --- /dev/null +++ b/rng.sv @@ -0,0 +1,19 @@ +module rng ( + input wire clk_in, + input wire [15:0] pc, + input bit keyboard [15:0], + input int cycle_counter, + output bit [7:0] rand_bit + ); + + bit [7:0] last; + + always_ff @(posedge clk_in) begin + for (int i = 0; i < 8; i++) begin + rand_bit[i] ^= ~keyboard[i] ? cycle_counter[i] : cycle_counter[7-i]; + rand_bit[i] ^= (cycle_counter % 7) == 0 ? pc[i] : ~pc[i]; + rand_bit[i] ^= keyboard[i+7] ? ~last[i] : last[i]; + end + last = rand_bit; + end +endmodule diff --git a/rom_loader.sv b/rom_loader.sv index 06d15cf..821d36e 100644 --- a/rom_loader.sv +++ b/rom_loader.sv @@ -1,24 +1,18 @@ module rom_loader ( - output bit [7:0] memory [0:4095], - output logic rom_ready + output bit [7:0] memory [0:4095] ); import "DPI-C" function int load_rom(); import "DPI-C" function bit [7:0] get_next_instr(); import "DPI-C" function void close_rom(); - int rom_size; - int i; - initial begin - rom_size = load_rom(); + int rom_size = load_rom(); $display("HW : ROM size is %0d bytes (%0d bits) (%0d instructions)", rom_size, rom_size * 8, rom_size / 2); - for (i = 0; i < rom_size; i++) begin + for (int i = 0; i < rom_size; i++) begin memory['h200 + i] = get_next_instr(); end close_rom(); $display("HW : ROM loaded successfully"); - $finish; - rom_ready = 1; end endmodule diff --git a/yayacemu.cpp b/yayacemu.cpp index 735c0cb..ac231b7 100644 --- a/yayacemu.cpp +++ b/yayacemu.cpp @@ -1,11 +1,9 @@ #include "svdpi.h" -#include "Vyayacemu__Dpi.h" -#include +#include "Vchip8__Dpi.h" +#include #include - -#include "Vyayacemu.h" +#include "Vchip8.h" #include "verilated.h" - #include #include #include @@ -34,11 +32,11 @@ void init_screen() { texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); - printf("INF_EMU: Screen initialized\n"); + std::cout << "INF_EMU: Screen initialized" << '\n'; } void set_beep(const svBit beep) { - if (beep > 0) + if (beep == 1) SDL_SetTextureColorMod(texture, 255, 0, 0); else SDL_SetTextureColorMod(texture, 255, 255, 255); @@ -49,28 +47,27 @@ void draw_screen(const svLogicVecVal* vram) { for(int i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { screen[i] = vram[i].aval; } - SDL_UpdateTexture(texture, NULL, screen, - sizeof(screen[0]) * SCREEN_WIDTH); + SDL_UpdateTexture(texture, NULL, screen, sizeof(screen[0]) * SCREEN_WIDTH); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); - printf("INF_EMU: Drawing Frame\n"); + free(screen); + std::cout << "INF_EMU: Drawing Frame" << '\n'; } int load_rom() { - printf("INF_EMU: Loading ROM %s\n", rom_name); - + std::cout << "INF_EMU: Loading ROM " << rom_name << '\n'; rom_file = fopen(rom_name, "r"); if (rom_file == NULL) { - printf("INF_EMU: Error reading ROM file. Panicing.\n"); + std::cout << "INF_EMU: Error reading ROM file. Panicing." << '\n'; exit(1); } fseek(rom_file, 0L, SEEK_END); int rom_size = ftell(rom_file); fseek(rom_file, 0L, SEEK_SET); - printf("INF_EMU: ROM size is %d bytes\n", rom_size); + std::cout << "INF_EMU: ROM size is %d bytes " << rom_size << '\n'; return rom_size; } @@ -83,13 +80,10 @@ void close_rom() { fclose(rom_file); } -int get_num() { - return 1; -} - svBitVecVal get_key() { SDL_Event event; uint8_t down = 0; + while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: @@ -142,25 +136,29 @@ svBitVecVal get_key() { int main(int argc, char** argv) { if (argc < 2) { - printf("Use: yayacemu [ROM_NAME]"); + std::cout << "Use: yayacemu [ROM_NAME]" << '\n'; exit(1); } + rom_name = argv[1]; + VerilatedContext* contextp = new VerilatedContext; contextp->commandArgs(argc, argv); - Vyayacemu* top = new Vyayacemu{contextp}; - //while (!contextp->gotFinish()) { - for (int i = 0; ; i++) { - top->clk_in ^= 1; - top->eval(); + + Vchip8* dut = new Vchip8{contextp}; + + while (true) { + dut->clk_in ^= 1; + dut->eval(); usleep(1000000/EMULATION_HZ); if (SDL_QuitRequested()) { - printf("Received Quit from SDL. Goodbye!\n"); + std::cout << "INF_EMU: Received Quit from SDL. Goodbye!" << '\n'; break; } } + fflush(stdout); - delete top; + delete dut; delete contextp; return 0; } diff --git a/yayacemu.sv b/yayacemu.sv deleted file mode 100644 index a1a180e..0000000 --- a/yayacemu.sv +++ /dev/null @@ -1,65 +0,0 @@ -module yayacemu ( - input wire clk_in - ); - wire [31:0] vram [0:2047]; - bit [7:0] memory [0:4095]; - wire [7:0] registers [0:15]; - logic [3:0] stack_pointer; - wire [15:0] stack [0:15]; - logic [7:0] delay_timer; - logic [7:0] sound_timer; - bit keyboard [15:0]; - int cycle_counter; - bit halt; - int watch_key; - - logic [15:0] index_reg; - bit [7:0] rand_num; - logic rom_ready; - logic [15:0] program_counter; - - bit [7:0] fontset [79:0]; - - randomizer randy(clk_in, program_counter, keyboard, cycle_counter, rand_num); - keyboard kb(clk_in, keyboard); - rom_loader rl (memory, rom_ready); - cpu cpu (memory, clk_in, keyboard, rand_num, vram, stack, index_reg, stack_pointer, registers, delay_timer, sound_timer, cycle_counter, program_counter, halt, watch_key); - beeper beeper(sound_timer); - gpu gpu (vram); - - int i; - initial begin - fontset = { - 8'hF0, 8'h90, 8'h90, 8'h90, 8'hF0, // 0 - 8'h20, 8'h60, 8'h20, 8'h20, 8'h70, // 1 - 8'hF0, 8'h10, 8'hF0, 8'h80, 8'hF0, // 2 - 8'hF0, 8'h10, 8'hF0, 8'h10, 8'hF0, // 3 - 8'h90, 8'h90, 8'hF0, 8'h10, 8'h10, // 4 - 8'hF0, 8'h80, 8'hF0, 8'h10, 8'hF0, // 5 - 8'hF0, 8'h80, 8'hF0, 8'h90, 8'hF0, // 6 - 8'hF0, 8'h10, 8'h20, 8'h40, 8'h40, // 7 - 8'hF0, 8'h90, 8'hF0, 8'h90, 8'hF0, // 8 - 8'hF0, 8'h90, 8'hF0, 8'h10, 8'hF0, // 9 - 8'hF0, 8'h90, 8'hF0, 8'h90, 8'h90, // A - 8'hE0, 8'h90, 8'hE0, 8'h90, 8'hE0, // B - 8'hF0, 8'h80, 8'h80, 8'h80, 8'hF0, // C - 8'hE0, 8'h90, 8'h90, 8'h90, 8'hE0, // D - 8'hF0, 8'h80, 8'hF0, 8'h80, 8'hF0, // E - 8'hF0, 8'h80, 8'hF0, 8'h80, 8'h80 // F - }; - watch_key = 255; - halt = 0; - for(i = 0; i < 80; i++) begin - memory[i] = fontset[i]; - end - for(i = 0; i < 15; i++) begin - keyboard[i] = 0; - end - sound_timer = 0; - delay_timer = 0; - cycle_counter = 0; - program_counter = 'h200; - stack_pointer = 4'b0000; - end - -endmodule