From 575e06df492dccdb779c834fc5e66481d8297d31 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Thu, 7 Jan 2016 22:15:27 +0800 Subject: [PATCH] [NES] Video module optimization. --- cores/nes/mist/NES_mist.v | 56 +++++++++----------- cores/nes/mist/clk.qip | 5 -- cores/nes/nes.qsf | 7 ++- cores/nes/src/vga.v | 108 -------------------------------------- cores/nes/src/video.v | 88 +++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 148 deletions(-) delete mode 100644 cores/nes/mist/clk.qip delete mode 100644 cores/nes/src/vga.v create mode 100644 cores/nes/src/video.v diff --git a/cores/nes/mist/NES_mist.v b/cores/nes/mist/NES_mist.v index eb2e1b7..29a3263 100644 --- a/cores/nes/mist/NES_mist.v +++ b/cores/nes/mist/NES_mist.v @@ -357,40 +357,34 @@ data_io data_io ( .d ( loader_input ) ); -wire nes_hs; -wire nes_vs; +video video ( + .clk(clk), + .sdi(SPI_DI), + .sck(SPI_SCK), + .ss(SPI_SS3), + + .color(color), + .count_v(scanline), + .count_h(cycle), + .mode(scandoubler_disable), + .smoothing(!status[1]), -VgaDriver vga( - .clk(clk), - .sdi(SPI_DI), - .sck(SPI_SCK), - .ss(SPI_SS3), - .color(color), - .nes_scanline(scanline), - .sync_line((cycle[8:3] == 42)), - .mode(scandoubler_disable), - .vga_smooth(!status[1]), - .border(1'b0), - - .vga_h(nes_hs), - .vga_v(nes_vs), - .VGA_R(VGA_R), - .VGA_G(VGA_G), - .VGA_B(VGA_B) + .VGA_HS(VGA_HS), + .VGA_VS(VGA_VS), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B) ); -assign VGA_HS = scandoubler_disable ? ~(nes_hs ^ nes_vs) : nes_hs; -assign VGA_VS = scandoubler_disable ? 1'b1 : nes_vs; - - assign AUDIO_R = audio; - assign AUDIO_L = audio; - wire audio; - sigma_delta_dac sigma_delta_dac ( - .DACout (audio), - .DACin (sample[15:8]), - .CLK (clk), - .RESET (reset_nes) - ); +assign AUDIO_R = audio; +assign AUDIO_L = audio; +wire audio; +sigma_delta_dac sigma_delta_dac ( + .DACout(audio), + .DACin(sample[15:8]), + .CLK(clk), + .RESET(reset_nes) +); assign LED = ~downloading; diff --git a/cores/nes/mist/clk.qip b/cores/nes/mist/clk.qip deleted file mode 100644 index 50105c6..0000000 --- a/cores/nes/mist/clk.qip +++ /dev/null @@ -1,5 +0,0 @@ -set_global_assignment -name IP_TOOL_NAME "ALTPLL" -set_global_assignment -name IP_TOOL_VERSION "13.1" -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "clk.v"] -set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "clk_bb.v"] -set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "clk.ppf"] diff --git a/cores/nes/nes.qsf b/cores/nes/nes.qsf index ebdc399..9e09951 100644 --- a/cores/nes/nes.qsf +++ b/cores/nes/nes.qsf @@ -291,17 +291,16 @@ set_global_assignment -name VERILOG_FILE mist/data_io.v set_global_assignment -name VERILOG_FILE mist/sdram.v set_global_assignment -name VERILOG_FILE mist/user_io.v set_global_assignment -name VERILOG_FILE mist/osd.v -set_global_assignment -name QIP_FILE mist/clk.qip +set_global_assignment -name VERILOG_FILE mist/clk.v set_global_assignment -name VERILOG_FILE src/compat.v set_global_assignment -name VERILOG_FILE src/ppu.v set_global_assignment -name VERILOG_FILE src/mmu.v set_global_assignment -name VERILOG_FILE src/cpu.v -set_global_assignment -name VERILOG_FILE src/vga.v -set_global_assignment -name VERILOG_FILE mist/NES_mist.v +set_global_assignment -name VERILOG_FILE src/video.v set_global_assignment -name VERILOG_FILE src/nes.v set_global_assignment -name VERILOG_FILE src/MicroCode.v set_global_assignment -name VERILOG_FILE src/hq2x.v set_global_assignment -name VERILOG_FILE src/dsp.v set_global_assignment -name VERILOG_FILE src/apu.v -set_global_assignment -name SIGNALTAP_FILE mist/stp.stp +set_global_assignment -name VERILOG_FILE mist/NES_mist.v set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/cores/nes/src/vga.v b/cores/nes/src/vga.v deleted file mode 100644 index be9c005..0000000 --- a/cores/nes/src/vga.v +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2012-2013 Ludvig Strigeus -// This program is GPL Licensed. See COPYING for the full license. - -module VgaDriver( - input clk, - input [5:0] color, // Pixel for current cycle. - input [8:0] nes_scanline, - input sync_line, - input mode, - input vga_smooth, - input border, - - input sck, - input ss, - input sdi, - - output reg vga_h, - output reg vga_v, - output [5:0] VGA_R, - output [5:0] VGA_G, - output [5:0] VGA_B -); - -// NES Palette -> RGB555 conversion -reg [15:0] pallut[0:63]; -initial $readmemh("nes_palette.txt", pallut); -wire [14:0] pixel = pallut[color][14:0]; - -// Horizontal and vertical counters -reg [9:0] h, v; -wire hpicture = (h < 512); // 512 lines of picture -wire hsync_on = (h == 512 + 23 + (mode ? 18 : 35)); // HSync ON, 23+35 pixels front porch -wire hsync_off = (h == 512 + 23 + (mode ? 18 : 35) + 82); // Hsync off, 82 pixels sync -wire hend = (h == 681); // End of line, 682 pixels. - -wire vpicture = (v < (480 >> mode)); // 480 lines of picture -wire vsync_on = hsync_on && (v == (mode ? 240 + 5 : 480 + 10)); // Vsync ON, 10 lines front porch. -wire vsync_off = hsync_on && (v == (mode ? 240 + 14 : 480 + 12)); // Vsync OFF, 2 lines sync signal -wire vend = (v == (523 >> mode)); // End of picture, 524 lines. (Should really be 525 according to NTSC spec) -wire inpicture = hpicture && vpicture; -wire [9:0] new_h = (hend || doubler_sync) ? 10'd0 : h + 10'd1; - -wire [14:0] doubler_pixel; -wire doubler_sync; - -Hq2x hq2x(clk, pixel, vga_smooth, // enabled - nes_scanline[8], // reset_frame - sync_line, // reset_line - {doubler_sync ? 1'b0 : hend ? !v[0] : v[0], new_h[8:0]}, // 0-511 for line 1, or 512-1023 for line 2. - doubler_sync, // new frame has just started - doubler_pixel); // pixel is outputted - -reg clk2 = 1'b0; -always @(posedge clk) clk2 <= ~clk2; -wire clkv = mode ? clk2 : clk; - -osd #(10'd0,10'd0,3'd4) osd ( - .pclk(clkv), - - .sck(sck), - .sdi(sdi), - .ss(ss), - - .red_in ({vga_r, 1'b0}), - .green_in({vga_g, 1'b0}), - .blue_in ({vga_b, 1'b0}), - .hs_in(vga_h), - .vs_in(vga_v), - - .red_out(VGA_R), - .green_out(VGA_G), - .blue_out(VGA_B) -); - -reg [4:0] vga_r; -reg [4:0] vga_g; -reg [4:0] vga_b; - -reg [8:0] old_scanline; -wire sync_frame = (old_scanline == 9'd511) && (nes_scanline == 9'd0); -always @(posedge clkv) begin - h <= (hend || (mode ? sync_frame : doubler_sync)) ? 10'd0 : h + 10'd1; - if(mode ? sync_frame : doubler_sync) begin - vga_v <= 1; - vga_h <= 1; - v <= 0; - end else begin - vga_h <= hsync_on ? 1'b0 : hsync_off ? 1'b1 : vga_h; - if (hend) - v <= vend ? 10'd0 : v + 10'd1; - vga_v <= vsync_on ? 1'b0 : vsync_off ? 1'b1 : vga_v; - vga_r <= mode ? pixel[4:0] : doubler_pixel[4:0]; - vga_g <= mode ? pixel[9:5] : doubler_pixel[9:5]; - vga_b <= mode ? pixel[14:10] : doubler_pixel[14:10]; - if (border && (h == 0 || h == 511 || v == 0 || v == (479 >> mode))) begin - vga_r <= 4'b1111; - vga_g <= 4'b1111; - vga_b <= 4'b1111; - end - if (!inpicture) begin - vga_r <= 4'b0000; - vga_g <= 4'b0000; - vga_b <= 4'b0000; - end - end - old_scanline <= nes_scanline; -end -endmodule diff --git a/cores/nes/src/video.v b/cores/nes/src/video.v new file mode 100644 index 0000000..824d216 --- /dev/null +++ b/cores/nes/src/video.v @@ -0,0 +1,88 @@ +// Copyright (c) 2012-2013 Ludvig Strigeus +// This program is GPL Licensed. See COPYING for the full license. + +module video( + input clk, + input [5:0] color, + input [8:0] count_h, + input [8:0] count_v, + input mode, + input smoothing, + + input sck, + input ss, + input sdi, + + output VGA_HS, + output VGA_VS, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B +); + +reg clk2 = 1'b0; +always @(posedge clk) clk2 <= ~clk2; +wire clkv = mode ? clk2 : clk; + +osd #(10'd0, 10'd0, 3'd4) osd ( + .pclk(clkv), + + .sck(sck), + .sdi(sdi), + .ss(ss), + + .red_in ({vga_r, 1'b0}), + .green_in({vga_g, 1'b0}), + .blue_in ({vga_b, 1'b0}), + .hs_in(sync_h), + .vs_in(sync_v), + + .red_out(VGA_R), + .green_out(VGA_G), + .blue_out(VGA_B) +); + +// NES Palette -> RGB555 conversion +reg [15:0] pallut[0:63]; +initial $readmemh("nes_palette.txt", pallut); +wire [14:0] pixel = pallut[color][14:0]; + +// Horizontal and vertical counters +reg [9:0] h, v; +wire hpicture = (h < 512); // 512 lines of picture +wire hend = (h == 681); // End of line, 682 pixels. + +wire vpicture = (v < (480 >> mode)); // 480 lines of picture +wire vend = (v == (523 >> mode)); // End of picture, 524 lines. (Should really be 525 according to NTSC spec) +wire [9:0] new_h = (hend || doubler_sync) ? 10'd0 : h + 10'd1; + +wire [14:0] doubler_pixel; +wire doubler_sync; + +Hq2x hq2x(clk, pixel, smoothing, // enabled + count_v[8], // reset_frame + (count_h[8:3] == 42), // reset_line + {doubler_sync ? 1'b0 : hend ? !v[0] : v[0], new_h[8:0]}, // 0-511 for line 1, or 512-1023 for line 2. + doubler_sync, // new frame has just started + doubler_pixel); // pixel is outputted + +reg [8:0] old_count_v; +wire sync_frame = (old_count_v == 9'd511) && (count_v == 9'd0); +always @(posedge clkv) begin + h <= (hend || (mode ? sync_frame : doubler_sync)) ? 10'd0 : h + 10'd1; + if(mode ? sync_frame : doubler_sync) v <= 0; + else if (hend) v <= vend ? 10'd0 : v + 10'd1; + + old_count_v <= count_v; +end + +wire [14:0] pixel_v = (!hpicture || !vpicture) ? 15'd0 : mode ? pixel : doubler_pixel; +wire [4:0] vga_r = pixel_v[4:0]; +wire [4:0] vga_g = pixel_v[9:5]; +wire [4:0] vga_b = pixel_v[14:10]; +wire sync_h = ((h >= (512 + 23 + (mode ? 18 : 35))) && (h < (512 + 23 + (mode ? 18 : 35) + 82))); +wire sync_v = ((v >= (mode ? 240 + 5 : 480 + 10)) && (v < (mode ? 240 + 14 : 480 + 12))); +assign VGA_HS = mode ? ~(sync_h ^ sync_v) : ~sync_h; +assign VGA_VS = mode ? 1'b1 : ~sync_v; + +endmodule