diff --git a/7-beep.ch8 b/7-beep.ch8 new file mode 100644 index 0000000..27c205f Binary files /dev/null and b/7-beep.ch8 differ 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 0000000..b0bff63 Binary files /dev/null and b/screenshots/beeper.png differ diff --git a/tests/7-beep.ch8 b/tests/7-beep.ch8 new file mode 100644 index 0000000..27c205f Binary files /dev/null and b/tests/7-beep.ch8 differ 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