From 75c1fbb1b9a6903de1810c8a3e193a9d36f577a1 Mon Sep 17 00:00:00 2001 From: Nicholas Orlowsky Date: Wed, 31 Jan 2024 13:53:10 -0600 Subject: [PATCH] everything but cleanup --- 7-beep.ch8 | Bin 0 -> 110 bytes README.md | 7 +++--- screenshots/beeper.png | Bin 0 -> 6767 bytes tests/7-beep.ch8 | Bin 0 -> 110 bytes yayacemu.cpp | 14 ++++++++---- yayacemu.sv | 47 ++++++++++++++++++++++++++++++----------- 6 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 7-beep.ch8 create mode 100644 screenshots/beeper.png create mode 100644 tests/7-beep.ch8 diff --git a/7-beep.ch8 b/7-beep.ch8 new file mode 100644 index 0000000000000000000000000000000000000000..27c205f7e1cb3a52c9314e8e0227aedd559bc24b GIT binary patch literal 110 zcmZ1!@*y>ev6&%-J4+^;XHm!}xsR!f(r<15An`#|N$1w~k3h1BDab&GPl(~kLLrL} z>;?=%It=d;7!qxgxEUUR)P9tBv{1+er03B*As->ELJ=_AMpElU_X#aY E02O^Dc>n+a literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 5fe96cb..7c3b78a 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,10 @@ yayacemu [PATH_TO_YOUR_ROM] - [x] More Instructions - [x] Tetris Working Running - [x] Pass Quirks Test -- [ ] Add beeper (instead of sound, screen becomes red) -- [ ] Implement a real random module +- [x] Add beeper (instead of sound, screen becomes red) +- [x] Add all Instructions +- [x] Implement a real (synthesizeable, pseudorandom) random module - [ ] Code cleanup -- [x] All Instructions ### Screenshots @@ -50,3 +50,4 @@ yayacemu [PATH_TO_YOUR_ROM] ![Flag Test Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/flags.png?raw=true) ![Quirk Test Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/quirks.png?raw=true) ![Tetris Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/tetris.png?raw=true) +![Beeper Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/beeper.png?raw=true) diff --git a/screenshots/beeper.png b/screenshots/beeper.png new file mode 100644 index 0000000000000000000000000000000000000000..b0bff63a8733511b5a4e7139838753efe3c20de7 GIT binary patch literal 6767 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 E02O^Dc>n+a literal 0 HcmV?d00001 diff --git a/yayacemu.cpp b/yayacemu.cpp index aadc835..7465205 100644 --- a/yayacemu.cpp +++ b/yayacemu.cpp @@ -14,7 +14,7 @@ #define SCREEN_WIDTH 64 #define SCREEN_HEIGHT 32 -#define EMULATION_HZ 4000 +#define EMULATION_HZ 2000 FILE *rom_file; SDL_Window *window; @@ -37,11 +37,15 @@ void init_screen() { printf("INF_EMU: Screen initialized\n"); } -void draw_screen(const svLogicVecVal* vram) { +void draw_screen(const svLogicVecVal* vram, const svBit beep) { uint32_t *screen = (uint32_t*) malloc(SCREEN_WIDTH*SCREEN_HEIGHT*32); for(int i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { screen[i] = vram[i].aval; } + if (beep > 0) + SDL_SetTextureColorMod(texture, 255, 0, 0); + else + SDL_SetTextureColorMod(texture, 255, 255, 255); SDL_UpdateTexture(texture, NULL, screen, sizeof(screen[0]) * SCREEN_WIDTH); SDL_RenderClear(renderer); @@ -147,10 +151,12 @@ int main(int argc, char** argv) { top->clk_in ^= 1; top->eval(); usleep(1000000/EMULATION_HZ); + if (SDL_QuitRequested()) { + printf("Received Quit from SDL. Goodbye!\n"); + break; + } } - printf("TB : Testbench has reached end of simulation. Pausing for 10 seconds before exiting"); fflush(stdout); - usleep(3000000); delete top; delete contextp; return 0; diff --git a/yayacemu.sv b/yayacemu.sv index 9cbbae7..b2ef5b3 100644 --- a/yayacemu.sv +++ b/yayacemu.sv @@ -16,13 +16,15 @@ module yayacemu ( int watch_key; logic [15:0] index_reg; + bit [7:0] rand_num; logic rom_ready; logic [15:0] program_counter; + randomizer randy(clk_in, program_counter, keyboard, cycle_counter, rand_num); keyboard kb(clk_in, keyboard); rom_loader rl (memory, rom_ready); - chip8_cpu cpu (memory, clk_in, keyboard, vram, stack, index_reg, stack_pointer, registers, delay_timer, sound_timer, cycle_counter, program_counter, halt, watch_key); - chip8_gpu gpu (vram); + chip8_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); + chip8_gpu gpu (vram, sound_timer); int i; initial begin @@ -53,10 +55,6 @@ module keyboard ( if (keyval != 8'b11111111) begin keyboard[keyval[3:0]] = keyval[7]; end - $display("%b", keyval); - for (i = 0; i < 16; i++) begin - $display("%0d %b", i, keyboard[i]); - end end endmodule @@ -64,6 +62,7 @@ module chip8_cpu( output bit [7:0] memory [0:4095], input wire clk_in, input wire keyboard [15:0], + input wire [7:0] random_number, output wire [31:0] vram [0:2047], output wire [15:0] stack [0:15], output wire [15:0] index_reg, @@ -230,7 +229,7 @@ module chip8_cpu( 'hc???: begin $display("HW : RND Vx, addr"); // TODO: use a real RNG module, this is not synthesizeable - scratch = {$urandom()%256}[15:0]; + scratch = {8'h00, random_number} % 16'h0100; scratch2 = (opcode & 'h00FF); registers[(opcode & 'h0F00) >> 8] = scratch[7:0] & scratch2[7:0]; end @@ -349,11 +348,35 @@ module chip8_cpu( end endmodule -module chip8_gpu ( - input wire [31:0] vram [0:2047] +// pseudo random number generator +module randomizer ( + input wire clk_in, + input wire [15:0] pc, + input bit keyboard [15:0], + input int cycle_counter, + output bit [7:0] rand_bit ); - import "DPI-C" function void draw_screen(logic [31:0] vram [0:2047]); - always_comb begin - draw_screen(vram); + + bit [7:0] last; + int i; + + always_ff @(posedge clk_in) begin + for (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; + $display("Randomizer is: %b", rand_bit); + end +endmodule + +module chip8_gpu ( + input wire [31:0] vram [0:2047], + input wire [7:0] sound_timer + ); + import "DPI-C" function void draw_screen(logic [31:0] vram [0:2047], bit beep); + always_comb begin + draw_screen(vram, sound_timer > 0); end endmodule