diff --git a/README.md b/README.md index 15b2e43..bfa2f94 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,9 @@ CD images can be stored as CHD or CUE/BIN format. Core Utilization: - Logic utilization (in ALMs) 24,631 / 41,910 ( 59 % ) - Total registers 29008 - Total block memory bits 1,896,711 / 5,662,720 ( 33 % ) + Logic utilization (in ALMs) 24,331 / 41,910 ( 58 % ) + Total registers 28509 + Total block memory bits 1,897,911 / 5,662,720 ( 34 % ) Total DSP Blocks 92 / 112 ( 82 % ) Expected synthesis times with Quartus 17.0.2 diff --git a/files.qip b/files.qip index 8477cb1..01ea7e4 100644 --- a/files.qip +++ b/files.qip @@ -30,6 +30,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/mpeg/fmv/mpeg_input_stream_fi set_global_assignment -name SYSTEMVERILOG_FILE rtl/mpeg/fmv/mpeg_video_start_code_decoder.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/mpeg/fmv/mpeg_video.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/mpeg/fmv/worker_firmware_memory.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/mpeg/fmv/yuv_frame_adr_fifo.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/mpeg/VexiiRiscv.v set_global_assignment -name SYSTEMVERILOG_FILE rtl/pointing_device.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/resetdelay.sv @@ -49,4 +50,4 @@ set_global_assignment -name VHDL_FILE tg68k/tg68dotc_verilog_wrapper.vhd set_global_assignment -name VHDL_FILE tg68k/TG68K_ALU.vhd set_global_assignment -name VHDL_FILE tg68k/TG68K_Pack.vhd set_global_assignment -name VHDL_FILE tg68k/TG68K.vhd -set_global_assignment -name VHDL_FILE tg68k/TG68KdotC_Kernel.vhd \ No newline at end of file +set_global_assignment -name VHDL_FILE tg68k/TG68KdotC_Kernel.vhd diff --git a/rtl/mcd212.sv b/rtl/mcd212.sv index 1247505..2117034 100644 --- a/rtl/mcd212.sv +++ b/rtl/mcd212.sv @@ -1243,9 +1243,6 @@ module mcd212 ( end vsd = backdrop_pixel && image_coding_method_register.ev; -`ifdef VERILATOR - vsd = 1; -`endif end // Implementation of Table 5-13 Register Map diff --git a/rtl/mpeg/demuxer.sv b/rtl/mpeg/demuxer.sv index 024a91f..0a554f8 100644 --- a/rtl/mpeg/demuxer.sv +++ b/rtl/mpeg/demuxer.sv @@ -8,48 +8,49 @@ module mpeg_demuxer ( output bit signed [32:0] system_clock_reference_start_time, output bit system_clock_reference_start_time_valid ); + parameter string unit = ""; enum bit [4:0] { - FMA_IDLE, - FMA_MAGIC0, - FMA_MAGIC1, - FMA_MAGIC2, - FMA_MAGIC3, - FMA_MAGIC_MATCH, - FMA_PACK0, - FMA_PACK1, - FMA_PACK2, - FMA_PACK3, - FMA_PACK4, - FMA_PACK5, - FMA_PES0, - FMA_PES1, - FMA_PES2, - FMA_PES3, - FMA_PES4, - FMA_PES5, - FMA_PES6, - FMA_PES7, - FMA_PES8, - FMA_PES_DTS0, - FMA_PES_DTS1, - FMA_PES_DTS2, - FMA_PES_DTS3, - FMA_PES_DTS4 + IDLE, + MAGIC0, + MAGIC1, + MAGIC2, + MAGIC3, + MAGIC_MATCH, + PACK0, + PACK1, + PACK2, + PACK3, + PACK4, + PACK5, + PES0, + PES1, + PES2, + PES3, + PES4, + PES5, + PES6, + PES7, + PES8, + PES_DTS0, + PES_DTS1, + PES_DTS2, + PES_DTS3, + PES_DTS4 - } demux_state = FMA_IDLE; + } demux_state = IDLE; bit packet_length_decreasing; bit [15:0] packet_length; bit signed [32:0] system_clock_reference; bit [9:0] pack_cnt = 0; - bit [32:0] presentation_time_stamp; - bit [32:0] decoding_time_stamp; + bit signed [32:0] presentation_time_stamp; + bit signed [32:0] decoding_time_stamp; bit dts_present; always_ff @(posedge clk) begin if (reset) begin - demux_state <= FMA_IDLE; + demux_state <= IDLE; system_clock_reference_start_time_valid <= 0; end else if (data_valid) begin @@ -64,140 +65,144 @@ module mpeg_demuxer ( casez ({ demux_state, mpeg_data }) + // verilog_format: off - {FMA_PACK5, 8'h??}: begin - demux_state <= FMA_IDLE; - $display ("FMA PACK %x %d",mpeg_data,system_clock_reference); + {PACK5, 8'h??}: begin + demux_state <= IDLE; + $display ("%s PACK %d", unit, system_clock_reference); end - {FMA_PACK4, 8'h??}: begin - demux_state <= FMA_PACK5; + {PACK4, 8'h??}: begin + demux_state <= PACK5; system_clock_reference[6:0] <= mpeg_data[7:1]; pack_cnt <= pack_cnt +1; end - {FMA_PACK3, 8'h??}: begin - demux_state <= FMA_PACK4; + {PACK3, 8'h??}: begin + demux_state <= PACK4; system_clock_reference[14:7] <= mpeg_data; end - {FMA_PACK2, 8'h??}: begin - demux_state <= FMA_PACK3; + {PACK2, 8'h??}: begin + demux_state <= PACK3; system_clock_reference[21:15] <= mpeg_data[7:1]; end - {FMA_PACK1, 8'h??}: begin - demux_state <= FMA_PACK2; + {PACK1, 8'h??}: begin + demux_state <= PACK2; system_clock_reference[29:22] <= mpeg_data; end - {FMA_PACK0, 8'h??}: begin - demux_state <= FMA_PACK1; + {PACK0, 8'h??}: begin + demux_state <= PACK1; system_clock_reference[32:30] <= mpeg_data[3:1]; end - {FMA_PES8, 8'h??}: begin - demux_state <= FMA_IDLE; - $display ("FMA PES %x %d",mpeg_data,presentation_time_stamp); + {PES8, 8'h??}: begin + demux_state <= IDLE; + + if (dts_present) + $display ("%s PES %d %d", unit, presentation_time_stamp, decoding_time_stamp); + else + $display ("%s PES %d", unit, presentation_time_stamp); - // verilog_format: on if (!system_clock_reference_start_time_valid) begin system_clock_reference_start_time_valid <= 1; system_clock_reference_start_time[32:1] <= dclk + presentation_time_stamp[32:1] - system_clock_reference[32:1]; end - // verilog_format: off end - {FMA_PES_DTS4, 8'b???????1}: begin // DTS + {PES_DTS4, 8'b???????1}: begin // DTS decoding_time_stamp[6:0] <= mpeg_data[7:1]; mpeg_packet_body <= 1; - demux_state <= FMA_PES8; + demux_state <= PES8; end - {FMA_PES_DTS3, 8'h??}: begin // DTS - demux_state <= FMA_PES_DTS4; + {PES_DTS3, 8'h??}: begin // DTS + demux_state <= PES_DTS4; decoding_time_stamp[14:7] <= mpeg_data; end - {FMA_PES_DTS2, 8'b???????1}: begin // DTS + {PES_DTS2, 8'b???????1}: begin // DTS decoding_time_stamp[21:15] <= mpeg_data[7:1]; - demux_state <= FMA_PES_DTS3; + demux_state <= PES_DTS3; end - {FMA_PES_DTS1, 8'h??}: begin // DTS - demux_state <= FMA_PES_DTS2; + {PES_DTS1, 8'h??}: begin // DTS + demux_state <= PES_DTS2; decoding_time_stamp[29:22] <= mpeg_data; end - {FMA_PES_DTS0, 8'b0001???1}: begin // DTS + {PES_DTS0, 8'b0001???1}: begin // DTS decoding_time_stamp[32:30] <= mpeg_data[3:1]; - demux_state <= FMA_PES_DTS1; + demux_state <= PES_DTS1; end - {FMA_PES7, 8'b???????1}: begin // PTS + {PES7, 8'b???????1}: begin // PTS presentation_time_stamp[6:0] <= mpeg_data[7:1]; if (dts_present) begin - demux_state <= FMA_PES_DTS0; + demux_state <= PES_DTS0; end else begin mpeg_packet_body <= 1; - demux_state <= FMA_PES8; + demux_state <= PES8; end end - {FMA_PES6, 8'h??}: begin // PTS - demux_state <= FMA_PES7; + {PES6, 8'h??}: begin // PTS + demux_state <= PES7; presentation_time_stamp[14:7] <= mpeg_data; end - {FMA_PES5, 8'b???????1}: begin // PTS + {PES5, 8'b???????1}: begin // PTS presentation_time_stamp[21:15] <= mpeg_data[7:1]; - demux_state <= FMA_PES6; + demux_state <= PES6; end - {FMA_PES4, 8'h??}: begin // PTS - demux_state <= FMA_PES5; + {PES4, 8'h??}: begin // PTS + demux_state <= PES5; presentation_time_stamp[29:22] <= mpeg_data; end - {FMA_PES2, 8'b0010???1}: begin // PTS (no DTS) + {PES2, 8'b0010???1}: begin // PTS (no DTS) presentation_time_stamp[32:30] <= mpeg_data[3:1]; dts_present <= 0; - demux_state <= FMA_PES4; + demux_state <= PES4; end - {FMA_PES2, 8'b0011???1}: begin // PTS and DTS + {PES2, 8'b0011???1}: begin // PTS and DTS presentation_time_stamp[32:30] <= mpeg_data[3:1]; dts_present <= 1; - demux_state <= FMA_PES4; + demux_state <= PES4; end - {FMA_PES2, 8'b00001111}: begin // Neither PTS nor DTS - demux_state <= FMA_IDLE; + {PES2, 8'b00001111}: begin // Neither PTS nor DTS + demux_state <= IDLE; mpeg_packet_body <= 1; + $display ("%s PES ...", unit); end - {FMA_PES3, 8'h??}: begin + {PES3, 8'h??}: begin // just ignore STD buffer size second byte - demux_state <= FMA_PES2; + demux_state <= PES2; end - {FMA_PES2, 8'b01??????}: begin // STD buffer size - demux_state <= FMA_PES3; + {PES2, 8'b01??????}: begin // STD buffer size + demux_state <= PES3; end - {FMA_PES2, 8'hff}: begin // stuffing byte - demux_state <= FMA_PES2; + {PES2, 8'hff}: begin // stuffing byte + demux_state <= PES2; end - {FMA_PES1, 8'h??}: begin - demux_state <= FMA_PES2; + {PES1, 8'h??}: begin + demux_state <= PES2; packet_length[7:0] <= mpeg_data; packet_length_decreasing <= 1; end - {FMA_PES0, 8'h??}: begin - demux_state <= FMA_PES1; + {PES0, 8'h??}: begin + demux_state <= PES1; packet_length[15:8] <= mpeg_data; end - {FMA_MAGIC_MATCH, 8'hba} : begin - demux_state <= FMA_PACK0; + {MAGIC_MATCH, 8'hba} : begin + demux_state <= PACK0; end - {FMA_MAGIC_MATCH, 8'hC?} : begin - demux_state <= FMA_PES0; + {MAGIC_MATCH, 8'hC?} : begin + demux_state <= PES0; end - {FMA_MAGIC_MATCH, 8'hE?} : begin - demux_state <= FMA_PES0; + {MAGIC_MATCH, 8'hE?} : begin + demux_state <= PES0; end - {FMA_MAGIC2, 8'h01} : demux_state <= FMA_MAGIC_MATCH; - {FMA_MAGIC2, 8'h00} : demux_state <= FMA_MAGIC2; - {FMA_MAGIC0, 8'h00} : demux_state <= FMA_MAGIC2; - {FMA_IDLE, 8'h00} : demux_state <= FMA_MAGIC0; - default: demux_state <= FMA_IDLE; + {MAGIC2, 8'h01} : demux_state <= MAGIC_MATCH; + {MAGIC2, 8'h00} : demux_state <= MAGIC2; + {MAGIC0, 8'h00} : demux_state <= MAGIC2; + {IDLE, 8'h00} : demux_state <= MAGIC0; + default: demux_state <= IDLE; // verilog_format: on endcase diff --git a/rtl/mpeg/fma/mpeg_audiofifo.sv b/rtl/mpeg/fma/mpeg_audiofifo.sv index c994f44..400f93c 100644 --- a/rtl/mpeg/fma/mpeg_audiofifo.sv +++ b/rtl/mpeg/fma/mpeg_audiofifo.sv @@ -21,13 +21,13 @@ module mpeg_audiofifo ( bit indizes_equal_during_write_d; bit indizes_equal_during_write_q; - assign out.write = count != 0 && !reset && !indizes_equal_during_write_q; - assign in.strobe = count < 510 && !reset && in.write; + assign out.write = count != 0 && !reset && !indizes_equal_during_write_q; + assign in.strobe = count < 510 && !reset && in.write; // Every MPEG synthesis will create 32 samples // Let's have at least 70 samples to not starve during frame change assign nearly_full = count >= 510; - assign half_full = count >= 70; + assign half_full = count >= 70; always_comb begin read_index_d = read_index_q; diff --git a/rtl/mpeg/fmv/dual_port_videoram.sv b/rtl/mpeg/fmv/dual_port_videoram.sv index 16a996a..3bf033a 100644 --- a/rtl/mpeg/fmv/dual_port_videoram.sv +++ b/rtl/mpeg/fmv/dual_port_videoram.sv @@ -60,4 +60,4 @@ module dual_port_videoram #( assign data_out2 = data_reg2; -endmodule : dual_port_videoram \ No newline at end of file +endmodule : dual_port_videoram diff --git a/rtl/mpeg/fmv/firmware.mem b/rtl/mpeg/fmv/firmware.mem index c629010..b7353eb 100644 --- a/rtl/mpeg/fmv/firmware.mem +++ b/rtl/mpeg/fmv/firmware.mem @@ -1,25 +1,25 @@ 00003117 -99010113 +9b010113 00002517 -94050513 +95850513 00002597 -93858593 +95058593 00002617 -fd460613 +fec60613 00c5fa63 00052283 0055a023 05910511 fec5eae3 00002517 -fb850513 +fd050513 00002597 -55458593 +56c58593 00b57763 00052023 6de30511 10effeb5 -203965e0 +20396760 0001a001 0001a001 00008082 @@ -35,7 +35,7 @@ c66ec86a 4601c398 2bc005b7 20000537 -27372ad1 +273722f5 431c1000 06934350 078e3e70 @@ -44,116 +44,122 @@ e8638f91 078e4350 fce38f91 4581fef6 -09372b69 +09372b4d 842a1000 03090913 -6b894c81 -6d096d89 +6d096b89 +6c896d89 0b300a93 49a54a09 ef99507c 8a63585c 24830157 85260904 -1ee32c01 +1ee32425 2a23ff55 85220354 -d16d2ca9 +d16d2c8d 4c054b0d 2023585c -91630149 +9d630149 20231007 85220139 -1c6010ef +1de010ef 57442783 -0693cff9 -44180f84 +0713cbfd +44140f84 463d445c 00c92023 -a703c298 -0785ff0b +a683c314 +0785008b 47edc45c 00f92023 -08638b05 -a7031007 -6789ff8d -fe47a783 -00371613 -0616963a +84638a85 +26831206 +a783010d +0593ffcd +96130380 +96360036 +06850616 +936397b2 +468100b6 +00dd2823 +11c7a683 +458dfef5 +100006b7 +10b7ae23 +cad04605 +11c7a603 +00b61663 +11c7a683 +fec68ee3 +008ba783 +a4230785 +f69300fb +c6cd0017 +010d2683 +ffcda783 03800593 -97b20705 -00b71363 -ac234701 -a703feed -ff7511c7 -0737458d +00369613 +06169636 +97b20685 +00b69363 +28234681 +a68300dd +fef511c7 +06b7458d ae231000 460510b7 -a603cb50 +a603cad0 166311c7 -a70300b6 -0ee311c7 -a783fec7 -0785ff0b -fefba823 -0017f713 -a703cb41 -6789ff8d -fe47a783 -00371613 -0616963a -03800593 -97b20705 -00b71363 -ac234701 -a703feed -ff7511c7 -0737458d -ae231000 -460510b7 -a603cb50 -166311c7 -a70300b6 -0ee311c7 -47f1fec7 +a68300b6 +8ee311c7 +47f1fec6 00f92023 -100007b7 -01978023 -0c854ad0 -cf90cb94 -5c1cb5e5 +07b74314 +c3941000 +01472883 +02c72803 +434c5308 +86be4710 +37b7ca98 +a0231000 +a2230117 +c7880107 +cb90c7cc +5c1cbdc1 03678063 57042783 -0693cf99 -bf210c84 +0713cf99 +b7010c84 09042483 20fd8526 2a23fd75 -bdd50204 -09840693 -2823b709 -bdf95784 -ff4d2603 +bdf10204 +09840713 +2823b5ed +b5d95784 +00cca603 a7836789 -1593fe07 +1593ff87 95b20036 05130596 06050380 036397ae -873200a6 -feed2a23 -2603bf8d -6789ff4d -fe07a783 +86b200a6 +00dca623 +a603bf99 +678900cc +ff87a783 00361593 059695b2 03800513 97ae0605 00a60363 -2a238732 -bdd5feed +a62386b2 +bde900dc a7036789 -1101fec7 +11010047 c64ec84a ce06c452 ca26cc22 @@ -173,11 +179,11 @@ cb158a32 00230731 640900d7 05134485 -46715744 -a6234581 -10effe97 +467158c4 +a2234581 +10ef0097 051347e0 -40f25744 +40f258c4 20234462 22230125 28230125 @@ -274,7 +280,7 @@ fee78de3 471cc71c 1c078d63 85936589 -8313f9c5 +8313fb45 461d0405 c50348a1 431c0005 @@ -296,7 +302,7 @@ c50348a1 471cc71c 18078d63 85936589 -8313f9c5 +8313fb45 461d0405 c50348a1 431c0005 @@ -391,14 +397,14 @@ d78ccfc8 610506a8 45018082 65898082 -f5c58593 +f7458593 04000613 4f050513 10efc642 48321ee0 6589b599 53080513 -f1c58593 +f3458593 04000613 10efc642 48321d60 @@ -407,9 +413,9 @@ f1c58593 c226c422 84aa842e 57800613 -ffc90513 +01490513 09134581 -c606ffc9 +c6060149 0d4010ef 08892a23 08992823 @@ -424,7 +430,7 @@ fe851ee3 48858082 93336809 081300b8 -45019e48 +45019fc8 10002737 4354431c 8de3078e @@ -527,19 +533,19 @@ df934017 73638d1d 80820065 23036509 -8a85ff05 +8a850085 73138b05 0d630013 6f890403 -ff8fa303 +010fa303 25036509 -1f13fe45 +1f13ffc5 9f1a0033 03050f16 03800293 0563957a -ac230653 -2303fe6f +a8230653 +2303006f 1a6311c5 28230403 d11c0105 @@ -553,15 +559,15 @@ c15001c5 47051000 8082cbd8 af036289 -6509ff42 -fe052503 +650900c2 +ff852503 003f1f93 0f969ffa 0f05957e 03800f93 01ff0363 -aa23837a -2303fe62 +a623837a +23030062 1ee311c5 b765fe03 bf614301 @@ -678,18 +684,18 @@ ce62d05e ca6acc66 db984721 a7836789 -8a2eff07 +8a2e0087 84638b85 66892e07 -ff86a783 +0106a783 28036709 -9713fe47 +9713ffc7 973e0037 07850716 03800613 8a63983a -ac2342c7 -2783fef6 +a82342c7 +278300f6 916311c8 20232e07 22230008 @@ -764,7 +770,7 @@ ac2342c7 873e00fa 16936789 87930027 -070a9487 +070a9607 033397b6 a88300e5 2683ff47 @@ -802,8 +808,8 @@ c7901000 10000337 03030313 8293197d -8f93f9c2 -45d1edcf +8f93fb42 +45d1ef4f 100027b7 03100713 03934e85 @@ -866,15 +872,15 @@ c7637ff0 03960633 00ca2023 6609bf1d -ff462703 +00c62703 a8036689 -1693fe06 +1693ff86 96ba0037 07050696 03800593 03639836 87ba00b7 -fef62a23 +00f62623 11c82783 bb31fff5 0007aa03 @@ -957,7 +963,7 @@ c86e019a b525f00c 53050f13 4781b359 -fef6ac23 +00f6a823 57fdb6f9 97b30705 8fd900c7 @@ -976,11 +982,11 @@ bdd197b2 47391000 c226c606 6709db98 -ff072783 +00872783 842a6589 -28230785 -8593fef7 -4601d9c5 +24230785 +859300f7 +4601db45 10002737 431c4505 078e4354 @@ -1034,7 +1040,7 @@ d87402f7 4c5c14f7 12f6df63 67895c18 -cec78793 +d0478793 97ba070a 46014388 10002737 @@ -1072,7 +1078,7 @@ cad1d43c 8b890604 10078563 c04a6589 -af458593 +b0c58593 27374601 45051000 4354431c @@ -1457,8 +1463,8 @@ ff010113 00002937 00112623 00912223 -94890913 -94840413 +96090913 +96040413 02890263 40890933 40295913 @@ -1470,8 +1476,8 @@ ff010113 ff24e8e3 00002937 00002437 -94890913 -94840413 +96090913 +96040413 02890263 40890933 40295913 @@ -1616,9 +1622,9 @@ fed70fa3 00158593 fc079ae3 f01ff06f -0000199c -00001954 -00001954 +000019b4 +0000196c +0000196c 00000002 00000004 00000000 @@ -1850,9 +1856,9 @@ fff50000 002f0000 001f0000 00000000 -00001d8c -00001d54 -00001cfc +00001da4 +00001d6c +00001d14 00000002 00000004 00000006 diff --git a/rtl/mpeg/fmv/frameplayer.sv b/rtl/mpeg/fmv/frameplayer.sv index a603195..b639dff 100644 --- a/rtl/mpeg/fmv/frameplayer.sv +++ b/rtl/mpeg/fmv/frameplayer.sv @@ -16,19 +16,19 @@ module frameplayer ( input hblank, input vblank, - input [28:0] frame_adr, + input planar_yuv_s frame, input latch_frame ); assign ddrif.byteenable = 8'hff; assign ddrif.write = 0; - bit [28:0] latched_frame_adr = 0; + planar_yuv_s latched_frame; always_ff @(posedge clkddr) begin if (latch_frame) begin - latched_frame_adr <= frame_adr; - $display("Latched frame %x", latched_frame_adr); + latched_frame <= frame; + //$display("Latched frame %x", latched_frame); end end @@ -173,9 +173,9 @@ module frameplayer ( if (reset_clkddr || vblank_clkddr) begin fetchstate <= IDLE; - address_y <= latched_frame_adr + 29'h0; - address_v <= latched_frame_adr + 29'h15900; // 368*240 = 88320 - address_u <= latched_frame_adr + 29'h1af40; // 368*240 + 88320/4 + address_y <= latched_frame.y_adr; + address_u <= latched_frame.u_adr; + address_v <= latched_frame.v_adr; target_y <= 0; target_u <= 0; target_v <= 0; diff --git a/rtl/mpeg/fmv/mpeg_input_stream_fifo_32k.sv b/rtl/mpeg/fmv/mpeg_input_stream_fifo_32k.sv index dbeace1..a793531 100644 --- a/rtl/mpeg/fmv/mpeg_input_stream_fifo_32k.sv +++ b/rtl/mpeg/fmv/mpeg_input_stream_fifo_32k.sv @@ -19,4 +19,4 @@ module mpeg_input_stream_fifo_32k ( always_ff @(posedge clkr) begin q <= ram[raddr]; end -endmodule : mpeg_input_stream_fifo_32k \ No newline at end of file +endmodule : mpeg_input_stream_fifo_32k diff --git a/rtl/mpeg/fmv/mpeg_video.sv b/rtl/mpeg/fmv/mpeg_video.sv index 140c514..ba51293 100644 --- a/rtl/mpeg/fmv/mpeg_video.sv +++ b/rtl/mpeg/fmv/mpeg_video.sv @@ -6,6 +6,7 @@ module mpeg_video ( input clk60, input reset, input dsp_enable, + input playback_active, input [7:0] data_byte, input data_strobe, @@ -698,12 +699,9 @@ module mpeg_video ( end endcase end - end - - // Assuming 90 MHz clock rate and 25 Hz frame rate - localparam TICKS_PER_FRAME = 1200000 * 3; + planar_yuv_s just_decoded; bit signed [15:0] shared_buffer_level = 0; @@ -761,6 +759,12 @@ module mpeg_video ( 4'd4: begin // Shared SRAM region end 4'd1: begin + if (dmem_cmd_payload_address_1[15:0] == 16'h3000) + just_decoded.y_adr <= dmem_cmd_payload_data_1[28:0]; + if (dmem_cmd_payload_address_1[15:0] == 16'h3004) + just_decoded.u_adr <= dmem_cmd_payload_data_1[28:0]; + if (dmem_cmd_payload_address_1[15:0] == 16'h3008) + just_decoded.v_adr <= dmem_cmd_payload_data_1[28:0]; end 4'd0: begin end @@ -1021,6 +1025,55 @@ module mpeg_video ( end end + + planar_yuv_s for_display; + wire just_decoded_commit = dmem_cmd_payload_write_1 && dmem_cmd_valid_1 && dmem_cmd_ready_1 && dmem_cmd_payload_address_1==32'h10003010; + wire for_display_valid; + bit for_display_strobe; + bit latch_frame_for_display; + wire latch_frame_for_display_clk60; + + // Assuming 30 MHz clock rate and 25 Hz frame rate + localparam bit [23:0] TICKS_PER_FRAME = 24'(int'(30e6) / 25); + bit [23:0] playback_frame_cnt; + + // In theory this machine could run with clk60. + // But I'm not so sure about the final frequency and timing is vital + always_ff @(posedge clk30) begin + latch_frame_for_display <= 0; + + if (!playback_active) playback_frame_cnt <= 0; + else begin + playback_frame_cnt <= playback_frame_cnt + 1; + + // Only for simulation. Ensure that frames are always available - no underflow + if (playback_frame_cnt == 0) assert (for_display_valid); + + if (playback_frame_cnt == TICKS_PER_FRAME - 1) playback_frame_cnt <= 0; + if (playback_frame_cnt == 0 && for_display_valid) latch_frame_for_display <= 1; + end + end + + flag_cross_domain cross_latch_frame ( + .clk_a(clk30), + .clk_b(clk60), + .flag_in_clk_a(latch_frame_for_display), + .flag_out_clk_b(latch_frame_for_display_clk60) + ); + + + yuv_frame_adr_fifo readyframes ( + .clk_in(clk60), + .reset_in(reset_dsp_enabled_clk60), + .wdata(just_decoded), + .we(just_decoded_commit), + .reset_out(reset_dsp_enabled_clk60), + .clk_out(clk60), + .strobe(latch_frame_for_display_clk60), + .valid(for_display_valid), + .q(for_display) + ); + frameplayer frameplayer ( .clk(clk30), .clkddr(clk60), @@ -1031,8 +1084,8 @@ module mpeg_video ( .vsync, .hblank, .vblank, - .frame_adr(dmem_cmd_payload_data_1[28:0]), - .latch_frame(expose_frame_y_adr_clk60) + .frame(for_display), + .latch_frame(latch_frame_for_display) ); endmodule diff --git a/rtl/mpeg/fmv/mpeg_video_start_code_decoder.sv b/rtl/mpeg/fmv/mpeg_video_start_code_decoder.sv index a63bb96..e781fb6 100644 --- a/rtl/mpeg/fmv/mpeg_video_start_code_decoder.sv +++ b/rtl/mpeg/fmv/mpeg_video_start_code_decoder.sv @@ -11,11 +11,13 @@ module mpeg_video_start_code_decoder ( output bit [31:0] timecode ); - bit [9:0] temperal_sequence_number; + bit [9:0] temporal_sequence_number; bit [9:0] next_sequence_number; bit [9:0] gop_cnt = 0; + bit [2:0] coding_type; + bit [15:0] vbv_delay; - enum bit [3:0] { + enum bit [4:0] { IDLE, MAGIC0, MAGIC1, @@ -30,6 +32,7 @@ module mpeg_video_start_code_decoder ( PIC1, PIC2, PIC3, + PIC4, SLICE0, SEQHDR } finder_state = IDLE; @@ -46,29 +49,38 @@ module mpeg_video_start_code_decoder ( }) // verilog_format: off - {PIC3, 8'h??}: begin finder_state <= IDLE; - $display ("PIC3 %x",mpeg_data); + {PIC4, 8'h??}: begin + finder_state <= IDLE; + $display ("PIC4 %d %d %d", temporal_sequence_number, coding_type, vbv_delay); event_picture <= 1; end + {PIC3, 8'h??}: begin + finder_state <= PIC4; + //$display ("PIC3"); + vbv_delay[4:0] <= mpeg_data[7:3]; + end {PIC2, 8'h??}: begin finder_state <= PIC3; - if (next_sequence_number == temperal_sequence_number) + if (next_sequence_number == temporal_sequence_number) begin - tmpref[11:2] <= temperal_sequence_number; - $display ("PIC2 %x %d",mpeg_data,temperal_sequence_number); + tmpref[11:2] <= temporal_sequence_number; + $display ("PIC2 %d", temporal_sequence_number); next_sequence_number <= next_sequence_number + 1; end - end + vbv_delay[12:5] <= mpeg_data; + end {PIC1, 8'h??}: begin finder_state <= PIC2; //$display ("PIC1 %x",mpeg_data); - temperal_sequence_number[1:0] <= mpeg_data[7:6]; - end + temporal_sequence_number[1:0] <= mpeg_data[7:6]; + coding_type <= mpeg_data[5:3]; + vbv_delay[15:13] <= mpeg_data[2:0]; + end {PIC0, 8'h??}: begin finder_state <= PIC1; //$display ("PIC0 %x",mpeg_data); - temperal_sequence_number[9:2] <= mpeg_data; - end + temporal_sequence_number[9:2] <= mpeg_data; + end {GOP3, 8'h??}: begin finder_state <= IDLE; $display ("GOP3 %x",mpeg_data); diff --git a/rtl/mpeg/fmv/worker_firmware_memory.sv b/rtl/mpeg/fmv/worker_firmware_memory.sv index 3da4c4f..bea689d 100644 --- a/rtl/mpeg/fmv/worker_firmware_memory.sv +++ b/rtl/mpeg/fmv/worker_firmware_memory.sv @@ -64,4 +64,4 @@ module worker_firmware_memory #( assign data_out2 = data_reg2; -endmodule : worker_firmware_memory \ No newline at end of file +endmodule : worker_firmware_memory diff --git a/rtl/mpeg/fmv/yuv_frame_adr_fifo.sv b/rtl/mpeg/fmv/yuv_frame_adr_fifo.sv new file mode 100644 index 0000000..d9c6232 --- /dev/null +++ b/rtl/mpeg/fmv/yuv_frame_adr_fifo.sv @@ -0,0 +1,80 @@ +`include "../util.svh" + +module yuv_frame_adr_fifo ( + // Input + input clk_in, + input reset_in, + input planar_yuv_s wdata, + input we, + // Output + input reset_out, + input clk_out, + input strobe, + output bit valid, + output planar_yuv_s q +); + + planar_yuv_s ram[16]; + + // Clock domain of output + bit [3:0] raddr; // 512 x 8 + + // Clock domain of input + bit [3:0] waddr; // 64 x 64 + + // verilog_format: off + // Transfer waddr from clk_in to clk_out + bit [3:0] waddr_gray; + b2g_converter #(.WIDTH(4)) waddr_to_gray1 (.binary(waddr),.gray(waddr_gray)); + bit [3:0] waddr_q; + bit [3:0] waddr_q2; + bit [3:0] waddr_q3; + always @(posedge clk_in) waddr_q <= waddr_gray; + always @(posedge clk_out) waddr_q2 <= waddr_q; + always @(posedge clk_out) waddr_q3 <= waddr_q2; + bit [3:0] waddr_clkout; + g2b_converter #(.WIDTH(4)) waddr_to_binary1 (.binary(waddr_clkout),.gray(waddr_q3)); + + // Transfer raddr from clk_out to clk_in + bit [3:0] raddr_gray; + b2g_converter #(.WIDTH(4)) raddr_to_gray2 (.binary(raddr),.gray(raddr_gray)); + bit [3:0] raddr_q; + bit [3:0] raddr_q2; + bit [3:0] raddr_q3; + always @(posedge clk_out) raddr_q <= raddr_gray; + always @(posedge clk_in) raddr_q2 <= raddr_q; + always @(posedge clk_in) raddr_q3 <= raddr_q2; + bit [3:0] raddr_clkin; + g2b_converter #(.WIDTH(4)) raddr_to_binary2 (.binary(raddr_clkin),.gray(raddr_q3)); + + // verilog_format: on + + wire [3:0] cnt_clkin = waddr - raddr_clkin; + wire [3:0] cnt_clkout = waddr_clkout - raddr; + + always_ff @(posedge clk_in) begin + if (reset_in) waddr <= 0; + else if (we) begin + ram[waddr] <= wdata; + waddr <= waddr + 1; + + assert (cnt_clkout < 10); + assert (cnt_clkin < 10); + end + end + + always_ff @(posedge clk_out) begin + if (reset_out) raddr <= 0; + else if (strobe) begin + raddr <= raddr + 1; + + assert (cnt_clkout > 0); + assert (cnt_clkin > 0); + end + + q <= ram[raddr]; + valid <= cnt_clkout != 0; + end + +endmodule : yuv_frame_adr_fifo + diff --git a/rtl/mpeg/util.svh b/rtl/mpeg/util.svh index fe5c216..bfa4c6b 100644 --- a/rtl/mpeg/util.svh +++ b/rtl/mpeg/util.svh @@ -1,6 +1,12 @@ `ifndef HEADER_UTIL `define HEADER_UTIL +typedef struct { + bit [28:0] y_adr; + bit [28:0] u_adr; + bit [28:0] v_adr; +} planar_yuv_s; + function [31:0] ones_mask(bit [4:0] n); begin ones_mask = (32'h1 << n) - 1; // n ones at LSB diff --git a/rtl/vmpeg.sv b/rtl/vmpeg.sv index d5e1807..8471829 100644 --- a/rtl/vmpeg.sv +++ b/rtl/vmpeg.sv @@ -99,12 +99,14 @@ module vmpeg ( // [5:0] 6 Bit Minutes? Not BCD // Where are the hours? wire [31:0] fmv_timecode; + bit fmv_playback_active; mpeg_video video ( .clk30(clk), .clk60(clk_mpeg), .reset, .dsp_enable(1'b1), + .playback_active(fmv_playback_active), .data_byte(mpeg_data), .data_strobe(fmv_data_valid && fmv_packet_body), .fifo_full(video_fifo_full), @@ -134,29 +136,35 @@ module vmpeg ( ); bit dsp_enable = 0; - wire signed [32:0] system_clock_reference_start_time; - wire system_clock_reference_start_time_valid; + wire signed [32:0] fma_system_clock_reference_start_time; + wire fma_system_clock_reference_start_time_valid; + wire signed [32:0] fmv_system_clock_reference_start_time; + wire fmv_system_clock_reference_start_time_valid; - mpeg_demuxer audio_demuxer ( + mpeg_demuxer #( + .unit("FMA") + ) audio_demuxer ( .clk, .reset(reset || (fma_command_register == 1)), .mpeg_data(mpeg_data), .data_valid(fma_data_valid), .mpeg_packet_body(fma_packet_body), .dclk(fma_dclk), - .system_clock_reference_start_time(system_clock_reference_start_time), - .system_clock_reference_start_time_valid(system_clock_reference_start_time_valid) + .system_clock_reference_start_time(fma_system_clock_reference_start_time), + .system_clock_reference_start_time_valid(fma_system_clock_reference_start_time_valid) ); - mpeg_demuxer video_demuxer ( + mpeg_demuxer #( + .unit("FMV") + ) video_demuxer ( .clk, .reset(reset), .mpeg_data(mpeg_data), .data_valid(fmv_data_valid), .mpeg_packet_body(fmv_packet_body), .dclk(fma_dclk), - .system_clock_reference_start_time(), - .system_clock_reference_start_time_valid() + .system_clock_reference_start_time(fmv_system_clock_reference_start_time), + .system_clock_reference_start_time_valid(fmv_system_clock_reference_start_time_valid) ); typedef struct packed { @@ -328,6 +336,8 @@ module vmpeg ( mpeg_ram_enabled_cnt <= 0; timer_cnt <= 0; dma_active <= 0; + dsp_enable <= 0; + fmv_playback_active <= 0; end else begin if (vsync && !vsync_q) interrupt_status_register.vsync <= 1; @@ -370,9 +380,14 @@ module vmpeg ( timer_cnt <= timer_cnt + 1; end - if (system_clock_reference_start_time_valid && fma_dclk == system_clock_reference_start_time[32:1] && !dsp_enable) begin + if (fma_system_clock_reference_start_time_valid && fma_dclk == fma_system_clock_reference_start_time[32:1] && !dsp_enable) begin dsp_enable <= 1; end + + if (fmv_system_clock_reference_start_time_valid && fma_dclk == fmv_system_clock_reference_start_time[32:1] && !fmv_playback_active) begin + fmv_playback_active <= 1; + end + end else begin fma_dclk_shadow_cnt <= fma_dclk_shadow_cnt + 1; end diff --git a/scripts/apply_codestyle.sh b/scripts/apply_codestyle.sh index 04238bf..4061989 100755 --- a/scripts/apply_codestyle.sh +++ b/scripts/apply_codestyle.sh @@ -4,4 +4,4 @@ cd "$(dirname "$0")/../rtl" verible-verilog-format --inplace --indentation_spaces 4 \ - ../rtl/*.v ../rtl/*.sv ../*.v ../*.sv + ../rtl/*.v ../rtl/*.sv ../rtl/*/*.sv ../rtl/*/*/*.sv ../*.v ../*.sv diff --git a/sim2/sim_top.cpp b/sim2/sim_top.cpp index c09cfc4..64b7b03 100644 --- a/sim2/sim_top.cpp +++ b/sim2/sim_top.cpp @@ -21,7 +21,7 @@ #define SCC68070 #define SLAVE -#define TRACE +// #define TRACE // #define SIMULATE_RC5 #define PL_MPEG_IMPLEMENTATION @@ -638,10 +638,13 @@ class CDi { } else { // PAL - - if (frame_index == 144) { // Skip Philips Logo - if ((frame_index % 25) == 20) - press_button_signal = true; + + if (frame_index == 137) { // Skip Philips Logo + press_button_signal = true; + } + + if (frame_index == 430) { // Skip Dragons Lair Intro + press_button_signal = true; } } @@ -869,7 +872,7 @@ class CDi { start = std::chrono::system_clock::now(); #ifdef TRACE - //do_trace = false; + do_trace = false; fprintf(stderr, "Trace off!\n"); #endif