1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-27 04:11:51 +00:00

[NES] Video module optimization.

This commit is contained in:
sorgelig
2016-01-07 22:15:27 +08:00
parent 3f92c4cdc4
commit 575e06df49
5 changed files with 116 additions and 148 deletions

View File

@@ -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;

View File

@@ -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"]

View File

@@ -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

View File

@@ -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

88
cores/nes/src/video.v Normal file
View File

@@ -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