From d4ec3f4afeeaa21725bcbd2e7a3f7065af11373b Mon Sep 17 00:00:00 2001 From: Rodrigo Batista de Moraes Date: Tue, 13 Feb 2024 16:28:49 -0300 Subject: [PATCH 01/12] Replace strength highz with weak Verilator don't support `highz` strengh, and I suppose `weak` has equivalent ordering compare to the order strengths used? --- dmg_cpu_b/dmg_cpu_b.sv | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dmg_cpu_b/dmg_cpu_b.sv b/dmg_cpu_b/dmg_cpu_b.sv index 6e09b11..c94662c 100644 --- a/dmg_cpu_b/dmg_cpu_b.sv +++ b/dmg_cpu_b/dmg_cpu_b.sv @@ -114,7 +114,7 @@ module dmg_cpu_b( for (genvar i = 0; i < 8; i++) assign d_pin_drv[i] = bidir_out(d_d[i], d_a[i]); endgenerate - assign (pull1, highz0) d_pin = {8{!lula}}; + assign (pull1, weak0) d_pin = {8{!lula}}; assign d_pin = d_pin_drv; logic [7:0] md_pin_drv; /* Value driven internally onto the pins if not 'z */ @@ -122,7 +122,7 @@ module dmg_cpu_b( for (genvar i = 0; i < 8; i++) assign md_pin_drv[i] = bidir_out(md_out[i], md_a[i]); endgenerate - assign (pull1, highz0) md_pin = {8{!md_b}}; + assign (pull1, weak0) md_pin = {8{!md_b}}; assign md_pin = md_pin_drv; generate @@ -135,8 +135,8 @@ module dmg_cpu_b( assign sout = nsout; assign sin = bidir_out(sin_d, sin_a); assign sck = bidir_out(sck_d, sck_a); - assign (pull1, highz0) sin = !sin_b; - assign (pull1, highz0) sck = !sck_dir; + assign (pull1, weak0) sin = !sin_b; + assign (pull1, weak0) sck = !sck_dir; assign p10 = bidir_out(p10_d, p10_a); assign p11 = bidir_out(p11_d, p11_a); @@ -144,10 +144,10 @@ module dmg_cpu_b( assign p13 = bidir_out(p13_d, p13_a); assign p14 = bidir_out(p14_b, p14_a); assign p15 = bidir_out(p15_b, p15_a); - assign (pull1, highz0) p10 = !p10_b; - assign (pull1, highz0) p11 = !p11_b; - assign (pull1, highz0) p12 = !p12_b; - assign (pull1, highz0) p13 = !p13_b; + assign (pull1, weak0) p10 = !p10_b; + assign (pull1, weak0) p11 = !p11_b; + assign (pull1, weak0) p12 = !p12_b; + assign (pull1, weak0) p13 = !p13_b; assign cpg = !npin_cpg; assign cp = !ncp; From a6472b9adfb7d77b4f8c24b1310716930b69edc1 Mon Sep 17 00:00:00 2001 From: Rodrigo Batista de Moraes Date: Tue, 13 Feb 2024 16:29:12 -0300 Subject: [PATCH 02/12] Add makefile recipe for building with verilator --- .gitignore | 1 + Makefile | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 789f338..8f034cd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /*.vid /*.mkv /DMG_ROM.bin +obj_dir diff --git a/Makefile b/Makefile index 50d815c..394ecab 100644 --- a/Makefile +++ b/Makefile @@ -197,3 +197,5 @@ test-cpu: $(TEST_DEPENDENCIES) test-boot: $(TEST_DEPENDENCIES) tests/run_tests.sh boot +verilator: + verilator -Wall --cc --trace --top-module dmg_cpu_b_gameboy --exe $(AV_DUMP) dmg_cpu_b_gameboy.sv $(DMG_CPU_B) $(SM83) $(MBC) From a52f0d85b023ead35d60aa6b89786d08ad5fc07d Mon Sep 17 00:00:00 2001 From: Rodrigo Batista de Moraes Date: Tue, 13 Feb 2024 16:39:21 -0300 Subject: [PATCH 03/12] Inline program test body in parent module Verilator don't support program decls inside a module. This may change the timing of things and cause data races? Not sure how much of a program is this. --- dmg_cpu_b_gameboy.sv | 196 +++++++++++++++++++++---------------------- 1 file changed, 97 insertions(+), 99 deletions(-) diff --git a/dmg_cpu_b_gameboy.sv b/dmg_cpu_b_gameboy.sv index 142d565..61d6020 100644 --- a/dmg_cpu_b_gameboy.sv +++ b/dmg_cpu_b_gameboy.sv @@ -5,7 +5,7 @@ module dmg_cpu_b_gameboy; import snd_dump::write_header; import snd_dump::write_bit4_as_int8; import snd_dump::write_real_as_int16; - vid_dump vdump(.*, .t(test.sample_idx)); + vid_dump vdump(.*, .t(sample_idx)); /* Clock (crystal) pins */ logic xi, xo; @@ -310,119 +310,117 @@ module dmg_cpu_b_gameboy; cpu_irq7_ack <= iack[7]; end - program test; - int sample_idx; + int sample_idx; - initial begin - string dumpfile, ch_file, snd_file, vid_file; - string time_str, prev_time_str; - real sim_seconds; - int _; - int fch[1:4]; - int fmix, fvid; - int sim_mcycs; - bit dump_channels, dump_sound, dump_video; - - dumpfile = ""; - _ = $value$plusargs("DUMPFILE=%s", dumpfile); - - ch_file = ""; - _ = $value$plusargs("CH_FILE=%s", ch_file); - dump_channels = ch_file != ""; - - snd_file = ""; - _ = $value$plusargs("SND_FILE=%s", snd_file); - dump_sound = snd_file != ""; - - vid_file = ""; - _ = $value$plusargs("VID_FILE=%s", vid_file); - dump_video = vid_file != ""; - - sim_seconds = 6.0; /* Enough time for the boot ROM */ - _ = $value$plusargs("SECS=%f", sim_seconds); - - sim_mcycs = $rtoi(sim_seconds * 1048576.0); - - $dumpfile(dumpfile); - $dumpvars(0, dmg_cpu_b_gameboy); - - if (dump_channels) for (int i = 1; i <= 4; i++) begin - string filename; - $sformat(filename, ch_file, i); - fch[i] = $fopen(filename, "wb"); - write_header(fch[i], 65536, 1, 0); - end - if (dump_sound) begin - fmix = $fopen(snd_file, "wb"); - write_header(fmix, 65536, 2, 1); - end - if (dump_video) - fvid = $fopen(vid_file, "wb"); + initial begin + string dumpfile, ch_file, snd_file, vid_file; + string time_str, prev_time_str; + real sim_seconds; + int _; + int fch[1:4]; + int fmix, fvid; + int sim_mcycs; + bit dump_channels, dump_sound, dump_video; + + dumpfile = ""; + _ = $value$plusargs("DUMPFILE=%s", dumpfile); + + ch_file = ""; + _ = $value$plusargs("CH_FILE=%s", ch_file); + dump_channels = ch_file != ""; + + snd_file = ""; + _ = $value$plusargs("SND_FILE=%s", snd_file); + dump_sound = snd_file != ""; + + vid_file = ""; + _ = $value$plusargs("VID_FILE=%s", vid_file); + dump_video = vid_file != ""; + + sim_seconds = 6.0; /* Enough time for the boot ROM */ + _ = $value$plusargs("SECS=%f", sim_seconds); + + sim_mcycs = $rtoi(sim_seconds * 1048576.0); + + $dumpfile(dumpfile); + $dumpvars(0, dmg_cpu_b_gameboy); + + if (dump_channels) for (int i = 1; i <= 4; i++) begin + string filename; + $sformat(filename, ch_file, i); + fch[i] = $fopen(filename, "wb"); + write_header(fch[i], 65536, 1, 0); + end + if (dump_sound) begin + fmix = $fopen(snd_file, "wb"); + write_header(fmix, 65536, 2, 1); + end + if (dump_video) + fvid = $fopen(vid_file, "wb"); - sample_idx = 0; + sample_idx = 0; - xi = 0; - nrst = 0; + xi = 0; + nrst = 0; - clk = 0; + clk = 0; - cpu_out_t1 = 0; - cpu_xo_ena = 1; + cpu_out_t1 = 0; + cpu_xo_ena = 1; - cyc(64); - nrst = 1; + cyc(64); + nrst = 1; - fork - begin :tick_tick - forever begin - cyc(64); - if (dump_channels) begin - write_bit4_as_int8(fch[1], dmg.ch1_out); - write_bit4_as_int8(fch[2], dmg.ch2_out); - write_bit4_as_int8(fch[3], dmg.wave_dac_d); - write_bit4_as_int8(fch[4], dmg.ch4_out); - end - if (dump_sound) begin - write_real_as_int16(fmix, lout); - write_real_as_int16(fmix, rout); - end - sample_idx++; + fork + begin :tick_tick + forever begin + cyc(64); + if (dump_channels) begin + write_bit4_as_int8(fch[1], dmg.ch1_out); + write_bit4_as_int8(fch[2], dmg.ch2_out); + write_bit4_as_int8(fch[3], dmg.wave_dac_d); + write_bit4_as_int8(fch[4], dmg.ch4_out); end + if (dump_sound) begin + write_real_as_int16(fmix, lout); + write_real_as_int16(fmix, rout); + end + sample_idx++; end + end - if (dump_video) begin :video_dump - vdump.video_dump_loop(fvid); - end + if (dump_video) begin :video_dump + vdump.video_dump_loop(fvid); + end - begin - @(negedge reset); - $sformat(time_str, "%.1f", $itor(sim_mcycs) / 1048576.0); - $display("System reset done -- will simulate %s seconds", time_str); - $fflush(32'h8000_0001); - prev_time_str = time_str; - - while (sim_mcycs) begin - sim_mcycs--; - if (sim_mcycs % 131072) begin - $sformat(time_str, "%.1f", $itor(sim_mcycs) / 1048576.0); - if (time_str != prev_time_str && time_str != "0.0") begin - $display("%s seconds remaining", time_str); - $fflush(32'h8000_0001); - prev_time_str = time_str; - end + begin + @(negedge reset); + $sformat(time_str, "%.1f", $itor(sim_mcycs) / 1048576.0); + $display("System reset done -- will simulate %s seconds", time_str); + $fflush(32'h8000_0001); + prev_time_str = time_str; + + while (sim_mcycs) begin + sim_mcycs--; + if (sim_mcycs % 131072) begin + $sformat(time_str, "%.1f", $itor(sim_mcycs) / 1048576.0); + if (time_str != prev_time_str && time_str != "0.0") begin + $display("%s seconds remaining", time_str); + $fflush(32'h8000_0001); + prev_time_str = time_str; end - @(posedge cpu_clkin_t9); - @(posedge cpu_clkin_t10); end - - disable tick_tick; - disable video_dump; + @(posedge cpu_clkin_t9); + @(posedge cpu_clkin_t10); end - join - $finish; - end - endprogram + disable tick_tick; + disable video_dump; + end + join + + $finish; + end /* HALT/EI/DI instruction test code */ /* From 17c58eafc5956a2bf9fa7f521d0d4842fed4a09e Mon Sep 17 00:00:00 2001 From: Rodrigo Batista de Moraes Date: Tue, 13 Feb 2024 16:57:05 -0300 Subject: [PATCH 04/12] Replace disable