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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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"]
|
||||
@@ -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
|
||||
@@ -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
88
cores/nes/src/video.v
Normal 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
|
||||
Reference in New Issue
Block a user