diff --git a/PCXT.qsf b/PCXT.qsf index 96ec8fd..7e70785 100644 --- a/PCXT.qsf +++ b/PCXT.qsf @@ -290,6 +290,10 @@ set_global_assignment -name EDA_GENERATE_FUNCTIONAL_NETLIST OFF -section_id eda_ set_global_assignment -name EDA_GENERATE_FUNCTIONAL_NETLIST OFF -section_id eda_board_design_signal_integrity set_global_assignment -name EDA_GENERATE_FUNCTIONAL_NETLIST OFF -section_id eda_board_design_boundary_scan set_global_assignment -name EDA_RUN_TOOL_AUTOMATICALLY OFF -section_id eda_simulation +set_global_assignment -name VERILOG_FILE rtl/video/mda_sequencer.v +set_global_assignment -name VERILOG_FILE rtl/video/mda_pixel.v +set_global_assignment -name VERILOG_FILE rtl/video/mda_attrib.v +set_global_assignment -name VERILOG_FILE rtl/video/mda.v set_global_assignment -name VERILOG_FILE rtl/uart/uart.v set_global_assignment -name QIP_FILE rtl/uart/uart.qip set_global_assignment -name VHDL_FILE rtl/uart/gh_uart_Tx_8bit.vhd @@ -403,4 +407,5 @@ set_global_assignment -name SYSTEMVERILOG_FILE PCXT.sv set_global_assignment -name SIP_FILE pll.sip set_global_assignment -name QIP_FILE rtl/pll.qip set_global_assignment -name SIP_FILE rtl/pll.sip +set_global_assignment -name VERILOG_FILE rtl/video/mda_vgaport.v set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/PCXT.sv b/PCXT.sv index 2e274db..40c0ac0 100644 --- a/PCXT.sv +++ b/PCXT.sv @@ -211,7 +211,9 @@ localparam CONF_STR = { "-;", "OA,Adlib,On,Invisible;", "-;", - "O12,Video,Color,Green,Amber,B/W;", + "O4,Video Output,Tandy/CGA,MDA;", + "O12,CGA RGB,Color,Green,Amber,B/W;", + "O56,MDA RGB,Green,Amber,B/W;", "O89,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];", //"O78,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;", "-;", @@ -314,7 +316,7 @@ wire pll_locked; wire clk_100; wire clk_28_636; -wire clk_25; +wire clk_56_875; reg clk_14_318 = 1'b0; //reg clk_7_16 = 1'b0; wire clk_4_77; @@ -329,6 +331,7 @@ pll pll .outclk_1(clk_28_636), .outclk_2(clk_uart), .outclk_3(cen_opl2), + .outclk_4(clk_56_875), .locked(pll_locked) ); @@ -468,8 +471,9 @@ always @(posedge clk_4_77) logic [7:0] port_b_out; logic [7:0] port_c_in; - logic [7:0] sw = 8'b00101101; // PCXT DIP Switches + reg [7:0] sw; + assign sw = status[4] ? 8'b00111101 : 8'b00101101; // PCXT DIP Switches (MDA or CGA 80) assign port_c_in[3:0] = port_b_out[3] ? sw[7:4] : sw[3:0]; CHIPSET u_CHIPSET ( @@ -486,8 +490,12 @@ always @(posedge clk_4_77) .processor_ready (processor_ready), .interrupt_to_cpu (interrupt_to_cpu), .splashscreen (splashscreen), - .clk_vga (clk_28_636), + .video_output (status[4]), + .clk_vga_cga (clk_28_636), .enable_cga (1'b1), + .clk_vga_mda (clk_56_875), + .enable_mda (1'b1), + .mda_rgb (status[6:5]), .de_o (VGA_DE), .VGA_R (r), .VGA_G (g), @@ -617,7 +625,7 @@ always @(posedge clk_4_77) ); */ - always @ (status[2:1], r, g, b) begin + always @ (status[2:1], r, g, b) begin case(status[2:1]) // Verde 2'b01 : begin @@ -646,9 +654,9 @@ always @(posedge clk_4_77) endcase end - assign VGA_R = {raux, 2'b0}; - assign VGA_G = {gaux, 2'b0}; - assign VGA_B = {baux, 2'b0}; + assign VGA_R = {status[4] ? r : raux, 2'b0}; + assign VGA_G = {status[4] ? g : gaux, 2'b0}; + assign VGA_B = {status[4] ? b : baux, 2'b0}; /* // SRAM management diff --git a/SW/splash.txt b/SW/splash.txt index 115f40f..6b83835 100644 --- a/SW/splash.txt +++ b/SW/splash.txt @@ -5,7 +5,7 @@ (_()((_|(_|_)) (_(_())/((_|()\ (_)) )\_____((_)(_(_()) | \/ |(_) __||_ _(_)) ((_) | _ ((/ __\ \/ /|_ _| | |\/| || \__ \ | | / -_)| '_| | _/| (__ > < | | - |_| |_||_|___/ |_| \___||_| |_| \___/_/\_\ |_| 07/06/2022 + |_| |_||_|___/ |_| \___||_| |_| \___/_/\_\ |_| 13/06/2022 Port by @spark2k06, @naeloob diff --git a/releases/PCXT_20220613.rbf b/releases/PCXT_20220613.rbf new file mode 100644 index 0000000..5010b32 Binary files /dev/null and b/releases/PCXT_20220613.rbf differ diff --git a/rtl/KFPC-XT/HDL/Chipset.sv b/rtl/KFPC-XT/HDL/Chipset.sv index b28099b..37d499d 100644 --- a/rtl/KFPC-XT/HDL/Chipset.sv +++ b/rtl/KFPC-XT/HDL/Chipset.sv @@ -18,8 +18,12 @@ module CHIPSET ( // SplashScreen input logic splashscreen, // VGA - input logic clk_vga, + input logic video_output, + input logic clk_vga_cga, input logic enable_cga, + input logic clk_vga_mda, + input logic enable_mda, + input logic [1:0] mda_rgb, output logic de_o, output logic [5:0] VGA_R, output logic [5:0] VGA_G, @@ -182,9 +186,13 @@ module CHIPSET ( .dma_chip_select_n (dma_chip_select_n), .dma_page_chip_select_n (dma_page_chip_select_n), .splashscreen (splashscreen), - .clk_vga (clk_vga), + .video_output (video_output), + .clk_vga_cga (clk_vga_cga), .enable_cga (enable_cga), + .clk_vga_mda (clk_vga_mda), + .enable_mda (enable_mda), .de_o (de_o), + .mda_rgb (mda_rgb), .VGA_R (VGA_R), .VGA_G (VGA_G), .VGA_B (VGA_B), diff --git a/rtl/KFPC-XT/HDL/Peripherals.sv b/rtl/KFPC-XT/HDL/Peripherals.sv index 90001d9..516768c 100644 --- a/rtl/KFPC-XT/HDL/Peripherals.sv +++ b/rtl/KFPC-XT/HDL/Peripherals.sv @@ -18,8 +18,12 @@ module PERIPHERALS #( // SplashScreen input logic splashscreen, // VGA - input logic clk_vga, + input logic video_output, + input logic clk_vga_cga, input logic enable_cga, + input logic clk_vga_mda, + input logic enable_mda, + input logic [1:0] mda_rgb, output logic de_o, output logic [5:0] VGA_R, output logic [5:0] VGA_G, @@ -108,7 +112,7 @@ module PERIPHERALS #( wire tandy_chip_select_n = ~(address[15:3] == (16'h00c0 >> 3)); // 0xc0 - 0xc7 wire opl_chip_select_n = ~(address[15:1] == (16'h0388 >> 1)); // 0x388 .. 0x389 wire cga_chip_select_n = ~(enable_cga & (address[19:14] == 6'b1011_10)); // B8000 - BFFFF (32 KB) - wire mda_chip_select_n = ~(enable_cga & (address[19:14] == 6'b1011_00)); // B0000 - B7FFF (32 KB) + wire mda_chip_select_n = ~(enable_mda & (address[19:14] == 6'b1011_00)); // B0000 - B7FFF (32 KB) wire rom_select_n = ~(address[19:16] == 4'b1111); // F0000 - FFFFF (64 KB) wire ram_select_n = ~(address[19:18] == 2'b00); // 00000 - 3FFFF (256 KB) wire uart_cs = ({address[15:3], 3'd0} == 16'h03F8); @@ -377,21 +381,84 @@ module PERIPHERALS #( uart_readdata <= uart_readdata; end + reg [5:0] R_CGA; + reg [5:0] G_CGA; + reg [5:0] B_CGA; + reg HSYNC_CGA; + reg VSYNC_CGA; - wire VRAM_ENABLE; - wire [18:0] VRAM_ADDR; - wire [7:0] VRAM_DOUT; - wire CRTC_OE; - wire [7:0] CRTC_DOUT; - + reg [5:0] R_MDA; + reg [5:0] G_MDA; + reg [5:0] B_MDA; + reg HSYNC_MDA; + reg VSYNC_MDA; + + reg de_o_cga; + reg de_o_mda; + + wire[3:0] video_cga; + wire[3:0] video_mda; + + assign VGA_R = video_output ? R_MDA : R_CGA; + assign VGA_G = video_output ? G_MDA : G_CGA; + assign VGA_B = video_output ? B_MDA : B_CGA; + assign VGA_HSYNC = video_output ? HSYNC_MDA : HSYNC_CGA; + assign VGA_VSYNC = video_output ? VSYNC_MDA : VSYNC_CGA; + assign de_o = video_output ? de_o_mda : de_o_cga; + + wire MDA_VRAM_ENABLE; + wire [18:0] MDA_VRAM_ADDR; + wire [7:0] MDA_VRAM_DOUT; + wire MDA_CRTC_OE; + wire [7:0] MDA_CRTC_DOUT; + + wire intensity; + + + + mda_vgaport vga_mda ( + .clk(clk_vga_mda), + .video(video_mda), + .intensity(intensity), + .red(R_MDA), + .green(G_MDA), + .blue(B_MDA), + .mda_rgb(mda_rgb) + ); + + mda mda1 ( + .clk (clk_vga_mda), + .bus_a (address[15:0]), + .bus_ior_l (io_read_n), + .bus_iow_l (io_write_n), + .bus_memr_l (1'd0), + .bus_memw_l (1'd0), + .bus_d (internal_data_bus), + .bus_out (MDA_CRTC_DOUT), + .bus_dir (MDA_CRTC_OE), + .bus_aen (address_enable_n), + .ram_we_l (MDA_VRAM_ENABLE), + .ram_a (MDA_VRAM_ADDR), + .ram_d (MDA_VRAM_DOUT), + .hsync (HSYNC_MDA), + .vsync (VSYNC_MDA), + .intensity (intensity), + .video (video_mda), + .de_o (de_o_mda) + ); + + + wire CGA_VRAM_ENABLE; + wire [18:0] CGA_VRAM_ADDR; + wire [7:0] CGA_VRAM_DOUT; + wire CGA_CRTC_OE; + wire [7:0] CGA_CRTC_DOUT; + // Sets up the card to generate a video signal // that will work with a standard VGA monitor // connected to the VGA port. parameter MDA_70HZ = 0; - - wire[3:0] vga_video; - wire[3:0] video; - + // wire composite_on; wire thin_font; @@ -401,61 +468,79 @@ module PERIPHERALS #( // Thin font switch (TODO: switchable with Keyboard shortcut) assign thin_font = 1'b0; // Default: No thin font + + // CGA digital to analog converter - cga_vgaport vga ( - .clk(clk_vga), -// .video(vga_video), - .video(video), //Mister Test without Scandouble - .red(VGA_R), - .green(VGA_G), - .blue(VGA_B) + cga_vgaport vga_cga ( + .clk(clk_vga_cga), + .video(video_cga), + .red(R_CGA), + .green(G_CGA), + .blue(B_CGA) ); cga cga1 ( - .clk (clk_vga), + .clk (clk_vga_cga), .bus_a (address[15:0]), .bus_ior_l (io_read_n), .bus_iow_l (io_write_n), .bus_memr_l (1'd0), .bus_memw_l (1'd0), .bus_d (internal_data_bus), - .bus_out (CRTC_DOUT), - .bus_dir (CRTC_OE), + .bus_out (CGA_CRTC_DOUT), + .bus_dir (CGA_CRTC_OE), .bus_aen (address_enable_n), - .ram_we_l (VRAM_ENABLE), - .ram_a (VRAM_ADDR), - .ram_d (VRAM_DOUT), -// .dbl_hsync (VGA_HSYNC), - .hsync (VGA_HSYNC), //Mister Test without Scandouble - .vsync (VGA_VSYNC), - .de_o (de_o), - .video (video), -// .dbl_video (vga_video), -// .comp_video (comp_video), + .ram_we_l (CGA_VRAM_ENABLE), + .ram_a (CGA_VRAM_ADDR), + .ram_d (CGA_VRAM_DOUT), + .hsync (HSYNC_CGA), + .vsync (VSYNC_CGA), + .de_o (de_o_cga), + .video (video_cga), .splashscreen (splashscreen), .thin_font (thin_font) ); - + defparam cga1.BLINK_MAX = 24'd4772727; + defparam mda1.BLINK_MAX = 24'd9100000; wire [7:0] ram_cpu_dout; wire [7:0] bios_cpu_dout; - wire [7:0] vram_cpu_dout; + wire [7:0] cga_vram_cpu_dout; + wire [7:0] mda_vram_cpu_dout; - vram vram + vram cga_vram ( .clka (clock), - .ena (~address_enable_n && (~mda_chip_select_n || ~cga_chip_select_n)), + .ena (~address_enable_n && ~cga_chip_select_n), .wea (~memory_write_n), .addra (address[14:0]), .dina (internal_data_bus), - .douta (vram_cpu_dout), - .clkb (clk_vga), + .douta (cga_vram_cpu_dout), + .clkb (clk_vga_cga), .web (1'b0), - .enb (VRAM_ENABLE), - .addrb (VRAM_ADDR[14:0]), + .enb (CGA_VRAM_ENABLE), + .addrb (CGA_VRAM_ADDR[14:0]), .dinb (8'h0), - .doutb (VRAM_DOUT) + .doutb (CGA_VRAM_DOUT) ); + + + vram mda_vram + ( + .clka (clock), + .ena (~address_enable_n && ~mda_chip_select_n), + .wea (~memory_write_n), + .addra (address[14:0]), + .dina (internal_data_bus), + .douta (mda_vram_cpu_dout), + .clkb (clk_vga_mda), + .web (1'b0), + .enb (MDA_VRAM_ENABLE), + .addrb (MDA_VRAM_ADDR[14:0]), + .dinb (8'h0), + .doutb (MDA_VRAM_DOUT) + ); + ram #(.AW(18)) mram @@ -528,9 +613,13 @@ module PERIPHERALS #( data_bus_out_from_chipset = 1'b1; data_bus_out = ppi_data_bus_out; end - else if ((~cga_chip_select_n || ~mda_chip_select_n) && (~memory_read_n)) begin + else if ((~cga_chip_select_n) && (~memory_read_n)) begin data_bus_out_from_chipset = 1'b1; - data_bus_out = vram_cpu_dout; + data_bus_out = cga_vram_cpu_dout; + end + else if ((~mda_chip_select_n) && (~memory_read_n)) begin + data_bus_out_from_chipset = 1'b1; + data_bus_out = mda_vram_cpu_dout; end else if ((~rom_select_n) && (~memory_read_n)) begin data_bus_out_from_chipset = 1'b1; @@ -540,9 +629,13 @@ module PERIPHERALS #( data_bus_out_from_chipset = 1'b1; data_bus_out = ram_cpu_dout; end - else if (CRTC_OE) begin + else if (CGA_CRTC_OE) begin data_bus_out_from_chipset = 1'b1; - data_bus_out = CRTC_DOUT; + data_bus_out = CGA_CRTC_DOUT; + end + else if (MDA_CRTC_OE) begin + data_bus_out_from_chipset = 1'b1; + data_bus_out = MDA_CRTC_DOUT; end else if ((~opl_chip_select_n) && (~io_read_n)) begin data_bus_out_from_chipset = 1'b1; diff --git a/rtl/pll.qip b/rtl/pll.qip index 6128d73..35bf73b 100644 --- a/rtl/pll.qip +++ b/rtl/pll.qip @@ -37,8 +37,8 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::dHJ1ZQ==::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::NA==::TnVtYmVyIE9mIENsb2Nrcw==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::NA==::bnVtYmVyX29mX2Nsb2Nrcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::NQ==::TnVtYmVyIE9mIENsb2Nrcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::NQ==::bnVtYmVyX29mX2Nsb2Nrcw==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" @@ -91,11 +91,11 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::NC43NzY=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::NTYuODc1::RGVzaXJlZCBGcmVxdWVuY3k=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MTY=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MTQ=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" @@ -270,7 +270,7 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::My41ODc0NDMgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::NTcuMTQyODU3IE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" @@ -355,12 +355,12 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMw==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMw==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMw==::ZmFsc2U=::Y19jbnRfYnlwYXNzX2VuMw==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMw==::dHJ1ZQ==::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMw==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2NA==::MQ==::Y19jbnRfaGlfZGl2NA==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2NA==::MQ==::Y19jbnRfbG9fZGl2NA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2NA==::Nw==::Y19jbnRfaGlfZGl2NA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2NA==::Nw==::Y19jbnRfbG9fZGl2NA==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDQ=::MQ==::Y19jbnRfcHJzdDQ=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q0::MA==::Y19jbnRfcGhfbXV4X3Byc3Q0" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjNA==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjNA==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuNA==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuNA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuNA==::ZmFsc2U=::Y19jbnRfYnlwYXNzX2VuNA==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNA==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNA==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2NQ==::MQ==::Y19jbnRfaGlfZGl2NQ==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2NQ==::MQ==::Y19jbnRfbG9fZGl2NQ==" @@ -463,8 +463,8 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX2ZiY2xrX211eF8y::bV9jbnQ=::cGxsX2ZiY2xrX211eF8y" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX21fY250X2luX3NyYw==::cGhfbXV4X2Nsaw==::cGxsX21fY250X2luX3NyYw==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3NsZl9yc3Q=::dHJ1ZQ==::cGxsX3NsZl9yc3Q=" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTMgSGkgRGl2aWRlLEMtQ291bnRlci0zIExvdyBEaXZpZGUsQy1Db3VudGVyLTMgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0zIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTMgSW5wdXQgU291cmNlLEMtQ291bnRlci0zIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTMgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::OCw4LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSw0LDQsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsMTQsMTQsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsMjE3LDIxNywxLDAscGhfbXV4X2NsayxmYWxzZSxmYWxzZSwxMTIsMTExLDEsMCxwaF9tdXhfY2xrLGZhbHNlLHRydWUsMSwyMCw0MDAwLDgwMC4wIE1IeiwxLG5vbmUsZ2xiLG1fY250LHBoX211eF9jbGssdHJ1ZQ==::UGFyYW1ldGVyIFZhbHVlcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTMgSGkgRGl2aWRlLEMtQ291bnRlci0zIExvdyBEaXZpZGUsQy1Db3VudGVyLTMgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0zIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTMgSW5wdXQgU291cmNlLEMtQ291bnRlci0zIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTMgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTQgSGkgRGl2aWRlLEMtQ291bnRlci00IExvdyBEaXZpZGUsQy1Db3VudGVyLTQgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci00IFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTQgSW5wdXQgU291cmNlLEMtQ291bnRlci00IEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTQgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::OCw4LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSw0LDQsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsMTQsMTQsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsMjE3LDIxNywxLDAscGhfbXV4X2NsayxmYWxzZSxmYWxzZSwxMTIsMTExLDEsMCxwaF9tdXhfY2xrLGZhbHNlLHRydWUsNyw3LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDEsMjAsNDAwMCw4MDAuMCBNSHosMSxub25lLGdsYixtX2NudCxwaF9tdXhfY2xrLHRydWU=::UGFyYW1ldGVyIFZhbHVlcw==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" diff --git a/rtl/pll.v b/rtl/pll.v index 80aa30b..7c9675d 100644 --- a/rtl/pll.v +++ b/rtl/pll.v @@ -12,6 +12,7 @@ module pll ( output wire outclk_1, // outclk1.clk output wire outclk_2, // outclk2.clk output wire outclk_3, // outclk3.clk + output wire outclk_4, // outclk4.clk output wire locked, // locked.export input wire [63:0] reconfig_to_pll, // reconfig_to_pll.reconfig_to_pll output wire [63:0] reconfig_from_pll // reconfig_from_pll.reconfig_from_pll @@ -24,6 +25,7 @@ module pll ( .outclk_1 (outclk_1), // outclk1.clk .outclk_2 (outclk_2), // outclk2.clk .outclk_3 (outclk_3), // outclk3.clk + .outclk_4 (outclk_4), // outclk4.clk .locked (locked), // locked.export .reconfig_to_pll (reconfig_to_pll), // reconfig_to_pll.reconfig_to_pll .reconfig_from_pll (reconfig_from_pll) // reconfig_from_pll.reconfig_from_pll @@ -71,7 +73,7 @@ endmodule // Retrieval info: // Retrieval info: // Retrieval info: -// Retrieval info: +// Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: @@ -112,7 +114,7 @@ endmodule // Retrieval info: // Retrieval info: // Retrieval info: -// Retrieval info: +// Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: diff --git a/rtl/pll/pll_0002.v b/rtl/pll/pll_0002.v index 415f92f..7d2fefe 100644 --- a/rtl/pll/pll_0002.v +++ b/rtl/pll/pll_0002.v @@ -19,6 +19,9 @@ module pll_0002( // interface 'outclk3' output wire outclk_3, + // interface 'outclk4' + output wire outclk_4, + // interface 'locked' output wire locked, @@ -35,7 +38,7 @@ module pll_0002( .pll_fractional_cout(32), .pll_dsm_out_sel("1st_order"), .operation_mode("direct"), - .number_of_clocks(4), + .number_of_clocks(5), .output_clock_frequency0("100.000000 MHz"), .phase_shift0("0 ps"), .duty_cycle0(50), @@ -48,7 +51,7 @@ module pll_0002( .output_clock_frequency3("3.587443 MHz"), .phase_shift3("0 ps"), .duty_cycle3(50), - .output_clock_frequency4("0 MHz"), + .output_clock_frequency4("57.142857 MHz"), .phase_shift4("0 ps"), .duty_cycle4(50), .output_clock_frequency5("0 MHz"), @@ -128,12 +131,12 @@ module pll_0002( .c_cnt_in_src3("ph_mux_clk"), .c_cnt_bypass_en3("false"), .c_cnt_odd_div_duty_en3("true"), - .c_cnt_hi_div4(1), - .c_cnt_lo_div4(1), + .c_cnt_hi_div4(7), + .c_cnt_lo_div4(7), .c_cnt_prst4(1), .c_cnt_ph_mux_prst4(0), .c_cnt_in_src4("ph_mux_clk"), - .c_cnt_bypass_en4("true"), + .c_cnt_bypass_en4("false"), .c_cnt_odd_div_duty_en4("false"), .c_cnt_hi_div5(1), .c_cnt_lo_div5(1), @@ -238,7 +241,7 @@ module pll_0002( .pll_slf_rst("true") ) altera_pll_i ( .rst (rst), - .outclk ({outclk_3, outclk_2, outclk_1, outclk_0}), + .outclk ({outclk_4, outclk_3, outclk_2, outclk_1, outclk_0}), .locked (locked), .reconfig_to_pll (reconfig_to_pll), .fboutclk ( ), diff --git a/rtl/video/mda.hex b/rtl/video/mda.hex new file mode 100644 index 0000000..bd2ab58 --- /dev/null +++ b/rtl/video/mda.hex @@ -0,0 +1 @@ +00 00 00 00 00 00 00 00 00 00 7E 81 A5 81 81 BD 00 00 7E FF DB FF FF C3 00 00 00 36 7F 7F 7F 7F 00 00 00 08 1C 3E 7F 3E 00 00 18 3C 3C E7 E7 E7 00 00 18 3C 7E FF FF 7E 00 00 00 00 00 18 3C 3C FF FF FF FF FF E7 C3 C3 00 00 00 00 3C 66 42 42 FF FF FF FF C3 99 BD BD 00 00 0F 07 0D 19 3C 66 00 00 3C 66 66 66 3C 18 00 00 3F 33 3F 30 30 30 00 00 7F 63 7F 63 63 63 00 00 18 18 DB 3C E7 3C 00 00 40 60 70 7C 7F 7C 00 00 01 03 07 1F 7F 1F 00 00 18 3C 7E 18 18 18 00 00 33 33 33 33 33 33 00 00 7F DB DB DB 7B 1B 00 3E 63 30 1C 36 63 63 00 00 00 00 00 00 00 00 00 00 18 3C 7E 18 18 18 00 00 18 3C 7E 18 18 18 00 00 18 18 18 18 18 18 00 00 00 00 0C 06 7F 06 00 00 00 00 18 30 7F 30 00 00 00 00 00 60 60 60 00 00 00 00 24 66 FF 66 00 00 00 08 1C 1C 3E 3E 00 00 00 7F 7F 3E 3E 1C 00 00 00 00 00 00 00 00 00 00 18 3C 3C 3C 18 18 00 63 63 63 22 00 00 00 00 00 36 36 7F 36 36 36 0C 0C 3E 63 61 60 3E 03 00 00 00 00 61 63 06 0C 00 00 1C 36 36 1C 3B 6E 00 30 30 30 60 00 00 00 00 00 0C 18 30 30 30 30 00 00 18 0C 06 06 06 06 00 00 00 00 66 3C FF 3C 00 00 00 18 18 18 FF 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 01 03 06 0C 18 30 00 00 3E 63 67 6F 7B 73 00 00 0C 1C 3C 0C 0C 0C 00 00 3E 63 03 06 0C 18 00 00 3E 63 03 03 1E 03 00 00 06 0E 1E 36 66 7F 00 00 7F 60 60 60 7E 03 00 00 1C 30 60 60 7E 63 00 00 7F 63 03 06 0C 18 00 00 3E 63 63 63 3E 63 00 00 3E 63 63 63 3F 03 00 00 00 18 18 00 00 00 00 00 00 18 18 00 00 00 00 00 06 0C 18 30 60 30 00 00 00 00 00 7E 00 00 00 00 60 30 18 0C 06 0C 00 00 3E 63 63 06 0C 0C 00 00 3E 63 63 6F 6F 6F 00 00 08 1C 36 63 63 7F 00 00 7E 33 33 33 3E 33 00 00 1E 33 61 60 60 60 00 00 7C 36 33 33 33 33 00 00 7F 33 31 34 3C 34 00 00 7F 33 31 34 3C 34 00 00 1E 33 61 60 60 6F 00 00 63 63 63 63 7F 63 00 00 3C 18 18 18 18 18 00 00 0F 06 06 06 06 06 00 00 73 33 36 36 3C 36 00 00 78 30 30 30 30 30 00 00 C3 E7 FF DB C3 C3 00 00 63 73 7B 7F 6F 67 00 00 1C 36 63 63 63 63 00 00 7E 33 33 33 3E 30 00 00 3E 63 63 63 63 6B 00 00 7E 33 33 33 3E 36 00 00 3E 63 63 30 1C 06 00 00 FF DB 99 18 18 18 00 00 63 63 63 63 63 63 00 00 C3 C3 C3 C3 C3 C3 00 00 C3 C3 C3 C3 DB DB 00 00 C3 C3 66 3C 18 3C 00 00 C3 C3 C3 66 3C 18 00 00 FF C3 86 0C 18 30 00 00 3C 30 30 30 30 30 00 00 40 60 70 38 1C 0E 00 00 3C 0C 0C 0C 0C 0C 08 1C 36 63 00 00 00 00 00 00 00 00 00 00 00 00 18 18 0C 00 00 00 00 00 00 00 00 00 00 3C 06 3E 00 00 70 30 30 3C 36 33 00 00 00 00 00 3E 63 60 00 00 0E 06 06 1E 36 66 00 00 00 00 00 3E 63 7F 00 00 1C 36 32 30 7C 30 00 00 00 00 00 3B 66 66 00 00 70 30 30 36 3B 33 00 00 0C 0C 00 1C 0C 0C 00 00 06 06 00 0E 06 06 00 00 70 30 30 33 36 3C 00 00 1C 0C 0C 0C 0C 0C 00 00 00 00 00 E6 FF DB 00 00 00 00 00 6E 33 33 00 00 00 00 00 3E 63 63 00 00 00 00 00 6E 33 33 00 00 00 00 00 3B 66 66 00 00 00 00 00 6E 3B 33 00 00 00 00 00 3E 63 38 00 00 08 18 18 7E 18 18 00 00 00 00 00 66 66 66 00 00 00 00 00 C3 C3 C3 00 00 00 00 00 C3 C3 DB 00 00 00 00 00 63 36 1C 00 00 00 00 00 63 63 63 00 00 00 00 00 7F 66 0C 00 00 0E 18 18 18 70 18 00 00 18 18 18 18 00 18 00 00 70 18 18 18 0E 18 00 00 3B 6E 00 00 00 00 00 00 00 00 08 1C 36 63 00 00 1E 33 61 60 60 61 00 00 66 66 00 66 66 66 00 06 0C 18 00 3E 63 7F 00 08 1C 36 00 3C 06 3E 00 00 66 66 00 3C 06 3E 00 30 18 0C 00 3C 06 3E 00 1C 36 1C 00 3C 06 3E 00 00 00 00 3C 66 60 66 00 08 1C 36 00 3E 63 7F 00 00 66 66 00 3E 63 7F 00 30 18 0C 00 3E 63 7F 00 00 66 66 00 38 18 18 00 18 3C 66 00 38 18 18 00 60 30 18 00 38 18 18 00 63 63 08 1C 36 63 63 1C 36 1C 00 1C 36 63 63 0C 18 30 00 7F 33 30 3E 00 00 00 00 6E 3B 1B 7E 00 00 1F 36 66 66 7F 66 00 08 1C 36 00 3E 63 63 00 00 63 63 00 3E 63 63 00 30 18 0C 00 3E 63 63 00 18 3C 66 00 66 66 66 00 30 18 0C 00 66 66 66 00 00 63 63 00 63 63 63 00 63 63 1C 36 63 63 63 00 63 63 00 63 63 63 63 00 18 18 7E C3 C0 C0 C3 00 1C 36 32 30 78 30 30 00 00 C3 66 3C 18 FF 18 00 FC 66 66 7C 62 66 6F 00 0E 1B 18 18 18 7E 18 00 0C 18 30 00 3C 06 3E 00 0C 18 30 00 38 18 18 00 0C 18 30 00 3E 63 63 00 0C 18 30 00 66 66 66 00 00 3B 6E 00 6E 33 33 3B 6E 00 63 73 7B 7F 6F 00 3C 6C 6C 3E 00 7E 00 00 38 6C 6C 38 00 7C 00 00 00 18 18 00 18 18 30 00 00 00 00 00 00 7F 60 00 00 00 00 00 00 7F 03 00 60 E0 63 66 6C 18 30 00 60 E0 63 66 6C 18 33 00 00 18 18 00 18 18 3C 00 00 00 00 1B 36 6C 36 00 00 00 00 6C 36 1B 36 11 44 11 44 11 44 11 44 55 AA 55 AA 55 AA 55 AA DD 77 DD 77 DD 77 DD 77 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 F8 18 18 18 18 18 F8 18 F8 36 36 36 36 36 36 36 F6 00 00 00 00 00 00 00 FE 00 00 00 00 00 F8 18 F8 36 36 36 36 36 F6 06 F6 36 36 36 36 36 36 36 36 00 00 00 00 00 FE 06 F6 36 36 36 36 36 F6 06 FE 36 36 36 36 36 36 36 FE 18 18 18 18 18 F8 18 F8 00 00 00 00 00 00 00 F8 18 18 18 18 18 18 18 1F 18 18 18 18 18 18 18 FF 00 00 00 00 00 00 00 FF 18 18 18 18 18 18 18 1F 00 00 00 00 00 00 00 FF 18 18 18 18 18 18 18 FF 18 18 18 18 18 1F 18 1F 36 36 36 36 36 36 36 37 36 36 36 36 36 37 30 3F 00 00 00 00 00 3F 30 37 36 36 36 36 36 F7 00 FF 00 00 00 00 00 FF 00 F7 36 36 36 36 36 37 30 37 00 00 00 00 00 FF 00 FF 36 36 36 36 36 F7 00 F7 18 18 18 18 18 FF 00 FF 36 36 36 36 36 36 36 FF 00 00 00 00 00 FF 00 FF 00 00 00 00 00 00 00 FF 36 36 36 36 36 36 36 3F 18 18 18 18 18 1F 18 1F 00 00 00 00 00 1F 18 1F 00 00 00 00 00 00 00 3F 36 36 36 36 36 36 36 FF 18 18 18 18 18 FF 18 FF 18 18 18 18 18 18 18 F8 00 00 00 00 00 00 00 1F FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 FF F0 F0 F0 F0 F0 F0 F0 F0 0F 0F 0F 0F 0F 0F 0F 0F FF FF FF FF FF FF FF 00 00 00 00 00 00 3B 6E 6C 00 00 00 00 3E 63 7E 63 00 00 7F 63 63 60 60 60 00 00 00 00 7F 36 36 36 00 00 7F 63 30 18 0C 18 00 00 00 00 00 3F 6C 6C 00 00 00 00 33 33 33 33 00 00 00 00 3B 6E 0C 0C 00 00 7E 18 3C 66 66 66 00 00 1C 36 63 63 7F 63 00 00 1C 36 63 63 63 36 00 00 1E 30 18 0C 3E 66 00 00 00 00 00 7E DB DB 00 00 03 06 7E DB DB F3 00 00 1C 30 60 60 7C 60 00 00 00 3E 63 63 63 63 00 00 00 7F 00 00 7F 00 00 00 18 18 18 FF 18 18 00 00 30 18 0C 06 0C 18 00 00 0C 18 30 60 30 18 00 00 0E 1B 1B 18 18 18 18 18 18 18 18 18 18 18 00 00 18 18 00 00 FF 00 00 00 00 00 3B 6E 00 3B 00 38 6C 6C 38 00 00 00 00 00 00 00 00 00 18 18 00 00 00 00 00 00 00 18 00 0F 0C 0C 0C 0C 0C EC 00 D8 6C 6C 6C 6C 6C 00 00 70 D8 30 60 C8 F8 00 00 00 00 00 3E 3E 3E 3E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 81 7E 00 00 00 00 00 E7 FF 7E 00 00 00 00 00 3E 1C 08 00 00 00 00 00 1C 08 00 00 00 00 00 00 18 18 3C 00 00 00 00 00 18 18 3C 00 00 00 00 00 18 00 00 00 00 00 00 00 E7 FF FF FF FF FF 00 00 66 3C 00 00 00 00 00 00 99 C3 FF FF FF FF 00 00 66 66 3C 00 00 00 00 00 7E 18 18 00 00 00 00 00 70 F0 E0 00 00 00 00 00 67 E7 E6 C0 00 00 00 00 DB 18 18 00 00 00 00 00 70 60 40 00 00 00 00 00 07 03 01 00 00 00 00 00 7E 3C 18 00 00 00 00 00 00 33 33 00 00 00 00 00 1B 1B 1B 00 00 00 00 00 36 1C 06 63 3E 00 00 00 7F 7F 7F 00 00 00 00 00 7E 3C 18 7E 00 00 00 00 18 18 18 00 00 00 00 00 7E 3C 18 00 00 00 00 00 0C 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 24 00 00 00 00 00 00 00 7F 7F 00 00 00 00 00 00 1C 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 18 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 36 36 00 00 00 00 00 43 63 3E 0C 0C 00 00 00 18 33 63 00 00 00 00 00 66 66 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 30 18 0C 00 00 00 00 00 06 0C 18 00 00 00 00 00 66 00 00 00 00 00 00 00 18 18 00 00 00 00 00 00 18 18 18 30 00 00 00 00 00 00 00 00 00 00 00 00 00 18 18 00 00 00 00 00 60 40 00 00 00 00 00 00 63 63 3E 00 00 00 00 00 0C 0C 3F 00 00 00 00 00 30 63 7F 00 00 00 00 00 03 63 3E 00 00 00 00 00 06 06 0F 00 00 00 00 00 03 63 3E 00 00 00 00 00 63 63 3E 00 00 00 00 00 18 18 18 00 00 00 00 00 63 63 3E 00 00 00 00 00 03 06 3C 00 00 00 00 00 18 18 00 00 00 00 00 00 18 18 30 00 00 00 00 00 18 0C 06 00 00 00 00 00 7E 00 00 00 00 00 00 00 18 30 60 00 00 00 00 00 00 0C 0C 00 00 00 00 00 6E 60 3E 00 00 00 00 00 63 63 63 00 00 00 00 00 33 33 7E 00 00 00 00 00 61 33 1E 00 00 00 00 00 33 36 7C 00 00 00 00 00 31 33 7F 00 00 00 00 00 30 30 78 00 00 00 00 00 63 33 1D 00 00 00 00 00 63 63 63 00 00 00 00 00 18 18 3C 00 00 00 00 00 66 66 3C 00 00 00 00 00 36 33 73 00 00 00 00 00 31 33 7F 00 00 00 00 00 C3 C3 C3 00 00 00 00 00 63 63 63 00 00 00 00 00 63 36 1C 00 00 00 00 00 30 30 78 00 00 00 00 00 6F 3E 06 07 00 00 00 00 33 33 73 00 00 00 00 00 63 63 3E 00 00 00 00 00 18 18 3C 00 00 00 00 00 63 63 3E 00 00 00 00 00 66 3C 18 00 00 00 00 00 FF 66 66 00 00 00 00 00 66 C3 C3 00 00 00 00 00 18 18 3C 00 00 00 00 00 61 C3 FF 00 00 00 00 00 30 30 3C 00 00 00 00 00 07 03 01 00 00 00 00 00 0C 0C 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 66 66 3B 00 00 00 00 00 33 33 6E 00 00 00 00 00 60 63 3E 00 00 00 00 00 66 66 3B 00 00 00 00 00 60 63 3E 00 00 00 00 00 30 30 78 00 00 00 00 00 66 3E 06 66 3C 00 00 00 33 33 73 00 00 00 00 00 0C 0C 1E 00 00 00 00 00 06 06 66 66 3C 00 00 00 36 33 73 00 00 00 00 00 0C 0C 1E 00 00 00 00 00 DB DB DB 00 00 00 00 00 33 33 33 00 00 00 00 00 63 63 3E 00 00 00 00 00 33 3E 30 30 78 00 00 00 66 3E 06 06 0F 00 00 00 30 30 78 00 00 00 00 00 0E 63 3E 00 00 00 00 00 18 1B 0E 00 00 00 00 00 66 66 3B 00 00 00 00 00 66 3C 18 00 00 00 00 00 DB FF 66 00 00 00 00 00 1C 36 63 00 00 00 00 00 63 3F 03 06 3C 00 00 00 18 33 7F 00 00 00 00 00 18 18 0E 00 00 00 00 00 18 18 18 00 00 00 00 00 18 18 70 00 00 00 00 00 00 00 00 00 00 00 00 00 63 7F 00 00 00 00 00 00 33 1E 06 03 3E 00 00 00 66 66 3B 00 00 00 00 00 60 63 3E 00 00 00 00 00 66 66 3B 00 00 00 00 00 66 66 3B 00 00 00 00 00 66 66 3B 00 00 00 00 00 66 66 3B 00 00 00 00 00 3C 0C 06 3C 00 00 00 00 60 63 3E 00 00 00 00 00 60 63 3E 00 00 00 00 00 60 63 3E 00 00 00 00 00 18 18 3C 00 00 00 00 00 18 18 3C 00 00 00 00 00 18 18 3C 00 00 00 00 00 7F 63 63 00 00 00 00 00 7F 63 63 00 00 00 00 00 30 33 7F 00 00 00 00 00 D8 DC 77 00 00 00 00 00 66 66 67 00 00 00 00 00 63 63 3E 00 00 00 00 00 63 63 3E 00 00 00 00 00 63 63 3E 00 00 00 00 00 66 66 3B 00 00 00 00 00 66 66 3B 00 00 00 00 00 63 3F 03 06 3C 00 00 00 63 36 1C 00 00 00 00 00 63 63 3E 00 00 00 00 00 7E 18 18 00 00 00 00 00 30 73 7E 00 00 00 00 00 FF 18 18 00 00 00 00 00 66 66 F3 00 00 00 00 00 18 18 18 D8 70 00 00 00 66 66 3B 00 00 00 00 00 18 18 3C 00 00 00 00 00 63 63 3E 00 00 00 00 00 66 66 3B 00 00 00 00 00 33 33 33 00 00 00 00 00 67 63 63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63 63 3E 00 00 00 00 00 60 60 00 00 00 00 00 00 03 03 00 00 00 00 00 00 6E C3 06 0C 1F 00 00 00 67 CF 1F 03 03 00 00 00 3C 3C 18 00 00 00 00 00 1B 00 00 00 00 00 00 00 6C 00 00 00 00 00 00 00 11 44 11 44 11 44 00 00 55 AA 55 AA 55 AA 00 00 DD 77 DD 77 DD 77 00 00 18 18 18 18 18 18 00 00 18 18 18 18 18 18 00 00 18 18 18 18 18 18 00 00 36 36 36 36 36 36 00 00 36 36 36 36 36 36 00 00 18 18 18 18 18 18 00 00 36 36 36 36 36 36 00 00 36 36 36 36 36 36 00 00 36 36 36 36 36 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 18 18 18 18 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 18 18 18 18 18 00 00 18 18 18 18 18 18 00 00 00 00 00 00 00 00 00 00 18 18 18 18 18 18 00 00 18 18 18 18 18 18 00 00 36 36 36 36 36 36 00 00 00 00 00 00 00 00 00 00 36 36 36 36 36 36 00 00 00 00 00 00 00 00 00 00 36 36 36 36 36 36 00 00 36 36 36 36 36 36 00 00 00 00 00 00 00 00 00 00 36 36 36 36 36 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 18 18 18 18 18 00 00 36 36 36 36 36 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 18 18 18 18 18 00 00 36 36 36 36 36 36 00 00 36 36 36 36 36 36 00 00 18 18 18 18 18 18 00 00 00 00 00 00 00 00 00 00 18 18 18 18 18 18 00 00 FF FF FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 F0 F0 F0 F0 F0 F0 00 00 0F 0F 0F 0F 0F 0F 00 00 00 00 00 00 00 00 00 00 6C 6E 3B 00 00 00 00 00 63 7E 60 60 20 00 00 00 60 60 60 00 00 00 00 00 36 36 36 00 00 00 00 00 30 63 7F 00 00 00 00 00 6C 6C 38 00 00 00 00 00 3E 30 30 60 00 00 00 00 0C 0C 0C 00 00 00 00 00 3C 18 7E 00 00 00 00 00 63 36 1C 00 00 00 00 00 36 36 77 00 00 00 00 00 66 66 3C 00 00 00 00 00 7E 00 00 00 00 00 00 00 7E 60 C0 00 00 00 00 00 60 30 1C 00 00 00 00 00 63 63 63 00 00 00 00 00 00 7F 00 00 00 00 00 00 18 00 FF 00 00 00 00 00 30 00 7E 00 00 00 00 00 0C 00 7E 00 00 00 00 00 18 18 18 18 18 18 00 00 D8 D8 70 00 00 00 00 00 00 18 18 00 00 00 00 00 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6C 3C 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3E 3E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ No newline at end of file diff --git a/rtl/video/mda.v b/rtl/video/mda.v new file mode 100644 index 0000000..9eff53a --- /dev/null +++ b/rtl/video/mda.v @@ -0,0 +1,270 @@ +// Graphics Gremlin +// +// Copyright (c) 2021 Eric Schlaepfer +// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +// International License. To view a copy of this license, visit +// http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative +// Commons, PO Box 1866, Mountain View, CA 94042, USA. +// +`default_nettype none +module mda( + // Clocks + input clk, + + // ISA bus + input[15:0] bus_a, + input bus_ior_l, + input bus_iow_l, + input bus_memr_l, + input bus_memw_l, + input[7:0] bus_d, + output[7:0] bus_out, + output bus_dir, + input bus_aen, + output bus_rdy, + + // RAM + output ram_we_l, + output[18:0] ram_a, + input[7:0] ram_d, + + // Video outputs + output hsync, + output vsync, + output de_o, + output video, + output intensity + ); + + parameter MDA_70HZ = 1; + parameter BLINK_MAX = 0; + + parameter IO_BASE_ADDR = 16'h3b0; // MDA is 3B0, CGA is 3D0 + wire crtc_cs; + wire status_cs; + wire control_cs; + wire bus_mem_cs; + + reg[7:0] bus_int_out; + wire[7:0] bus_out_crtc; + wire[7:0] bus_out_mem; + wire[7:0] mda_status_reg; + reg[7:0] mda_control_reg = 8'b0010_1000; + wire video_enabled; + wire blink_enabled; + + wire hsync_int; + wire vsync_l; + wire cursor; +// wire video; + wire display_enable; +// wire intensity; + + wire[13:0] crtc_addr; + wire[4:0] row_addr; + + wire charrom_read; + wire disp_pipeline; + wire isa_op_enable; + wire vram_read_char; + wire vram_read_att; + wire vram_read; + wire vram_read_a0; + wire[4:0] clkdiv; + wire crtc_clk; + wire[7:0] ram_1_d; + + reg[23:0] blink_counter; + reg blink; + + reg bus_memw_synced_l; + reg bus_memr_synced_l; + reg bus_ior_synced_l; + reg bus_iow_synced_l; + + //wire cpu_memsel; + //reg[1:0] wait_state = 2'd0; + //reg bus_rdy_latch; + + assign de_o = display_enable; + + assign ram_a = {7'b0000000, crtc_addr[10:0], + vram_read_a0}; + + assign ram_1_d = ram_d; + //assign ram_1_d = 8'hFF; + assign ram_we_l = vram_read; + + + // Synchronize ISA bus control lines to our clock + always @ (posedge clk) + begin + //bus_memw_synced_l <= bus_memw_l; + //bus_memr_synced_l <= bus_memr_l; + bus_ior_synced_l <= bus_ior_l; + bus_iow_synced_l <= bus_iow_l; + end + + // Some modules need a non-inverted vsync trigger + assign vsync = ~vsync_l; + + // Mapped IO + assign crtc_cs = (bus_a[15:3] == IO_BASE_ADDR[15:3]) & ~bus_aen; // 3B4/3B5 + assign status_cs = (bus_a == IO_BASE_ADDR + 20'hA) & ~bus_aen; + assign control_cs = (bus_a == IO_BASE_ADDR + 16'h8) & ~bus_aen; + + // Memory-mapped from B0000 to B7FFF + // assign bus_mem_cs = (bus_a[19:15] == 5'b10110); + + // Mux ISA bus data from every possible internal source. + always @ (*) + begin +// if (bus_mem_cs & ~bus_memr_l) begin +// bus_int_out <= bus_out_mem; + if (status_cs & ~bus_ior_l) begin + bus_int_out <= mda_status_reg; + end else if (crtc_cs & ~bus_ior_l & (bus_a[0] == 1)) begin + bus_int_out <= bus_out_crtc; + end else begin + bus_int_out <= 8'h00; + end + end + + // Only for read operations does bus_dir go high. + assign bus_dir = (crtc_cs | status_cs) & ~bus_ior_l; + // | (bus_mem_cs & ~bus_memr_l); + //assign bus_dir = (crtc_cs | status_cs); + assign bus_out = bus_int_out; + + + // MDA status register (read only at 3BA) + assign mda_status_reg = {4'b1111, video, 2'b00, hsync_int}; + + // MDA mode control register (write only) + assign blink_enabled = mda_control_reg[5]; + assign video_enabled = mda_control_reg[3]; + + // Hsync only present when video is enabled + assign hsync = video_enabled & hsync_int; + + // Update control register + always @ (posedge clk) + begin + if (control_cs & ~bus_iow_synced_l) begin + mda_control_reg <= bus_d; + end + end + + // CRT controller (MC6845 compatible) + crtc6845 crtc ( + .clk(clk), + .divclk(crtc_clk), + .cs(crtc_cs), + .a0(bus_a[0]), + .write(~bus_iow_synced_l), + .read(~bus_ior_synced_l), + .bus(bus_d), + .bus_out(bus_out_crtc), + .lock(MDA_70HZ == 1), + .hsync(hsync_int), + .vsync(vsync_l), + .display_enable(display_enable), + .cursor(cursor), + .mem_addr(crtc_addr), + .row_addr(row_addr) + ); + + +// if (MDA_70HZ) begin + defparam crtc.H_TOTAL = 8'd99; + defparam crtc.H_DISP = 8'd80; + defparam crtc.H_SYNCPOS = 8'd82; + defparam crtc.H_SYNCWIDTH = 4'd12; + defparam crtc.V_TOTAL = 7'd31; + defparam crtc.V_TOTALADJ = 5'd1; + defparam crtc.V_DISP = 7'd25; + defparam crtc.V_SYNCPOS = 7'd27; + defparam crtc.V_MAXSCAN = 5'd13; + defparam crtc.C_START = 7'd11; + defparam crtc.C_END = 5'd12; +// end else begin + /* + defparam crtc.H_TOTAL = 8'd97; + defparam crtc.H_DISP = 8'd80; + defparam crtc.H_SYNCPOS = 8'd82; + defparam crtc.H_SYNCWIDTH = 4'd15; + defparam crtc.V_TOTAL = 7'd25; + defparam crtc.V_TOTALADJ = 5'd6; + defparam crtc.V_DISP = 7'd25; + defparam crtc.V_SYNCPOS = 7'd25; + defparam crtc.V_MAXSCAN = 5'd13; + defparam crtc.C_START = 7'd11; + defparam crtc.C_END = 5'd12; + //end + + // Interface to video SRAM chip + mda_vram video_buffer ( + .clk(clk), + .isa_addr({3'b000, bus_a[15:0]}), + .isa_din(bus_d), + .isa_dout(bus_out_mem), + .isa_read(bus_mem_cs & ~bus_memr_synced_l), + .isa_write(bus_mem_cs & ~bus_memw_synced_l), + .pixel_addr({7'h00, crtc_addr[10:0], vram_read_a0}), + .pixel_data(ram_1_d), + .pixel_read(vram_read), + .ram_a(ram_a), + .ram_d(ram_d), + .ram_we_l(ram_we_l), + .isa_op_enable(isa_op_enable) + ); + + defparam video_buffer.MDA_70HZ = MDA_70HZ; +*/ + // Sequencer state machine + mda_sequencer sequencer ( + .clk(clk), + .clk_seq(clkdiv), + .vram_read(vram_read), + .vram_read_a0(vram_read_a0), + .vram_read_char(vram_read_char), + .vram_read_att(vram_read_att), + .crtc_clk(crtc_clk), + .charrom_read(charrom_read), + .disp_pipeline(disp_pipeline), + .isa_op_enable(isa_op_enable) + ); + + defparam sequencer.MDA_70HZ = MDA_70HZ; + + // Pixel pusher + mda_pixel pixel ( + .clk(clk), + .clk_seq(clkdiv), + .vram_data(ram_1_d), + .vram_read_char(vram_read_char), + .vram_read_att(vram_read_att), + .disp_pipeline(disp_pipeline), + .charrom_read(charrom_read), + .display_enable(display_enable), + .cursor(cursor), + .row_addr(row_addr), + .blink_enabled(blink_enabled), + .blink(blink), + .video_enabled(video_enabled), + .video(video), + .intensity(intensity) + ); + + // Generate blink signal for cursor and character + always @ (posedge clk) + begin + if (blink_counter == BLINK_MAX) begin + blink_counter <= 0; + blink <= ~blink; + end else begin + blink_counter <= blink_counter + 1; + end + end + +endmodule diff --git a/rtl/video/mda_attrib.v b/rtl/video/mda_attrib.v new file mode 100644 index 0000000..78559c2 --- /dev/null +++ b/rtl/video/mda_attrib.v @@ -0,0 +1,69 @@ +// Graphics Gremlin +// +// Copyright (c) 2021 Eric Schlaepfer +// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +// International License. To view a copy of this license, visit +// http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative +// Commons, PO Box 1866, Mountain View, CA 94042, USA. +// +`default_nettype none +module mda_attrib( + input clk, + input[7:0] att_byte, + input[4:0] row_addr, + input display_enable, + input blink_enabled, + input blink, + input cursor, + input pix_in, + output pix_out, + output intensity_out + ); + + reg blinkdiv; + reg[1:0] blink_old; + wire att_inverse; + wire att_underline; + wire att_blink; + wire att_nodisp; + wire[2:0] att_fg; + wire[2:0] att_bg; + wire cursorblink; + wire blink_area; + wire vid_underline; + wire intensity_bg; + wire intensity_fg; + wire alpha_dots; + + // Extract attributes from the attribute byte + assign att_fg = att_byte[2:0]; + assign att_bg = att_byte[6:4]; + assign att_underline = (att_fg == 3'b001) & (row_addr==5'd12); + assign intensity_bg = att_byte[7] & ~blink_enabled; + assign intensity_fg = att_byte[3]; + assign att_inverse = (att_fg == 3'b000) & (att_bg == 3'b111); + assign att_nodisp = (att_fg == 3'b000) & (att_bg == 3'b000); + assign att_blink = att_byte[7]; + + // Character blink is half the rate of the cursor blink + always @ (posedge clk) + begin + blink_old <= {blink_old[0], blink}; + if (blink_old == 2'b01) begin + blinkdiv <= ~blinkdiv; + end + end + + // Assemble all the signals to create the final video signal + assign cursorblink = cursor & blink; + assign blink_area = att_blink & blinkdiv & ~cursor & blink_enabled; + assign vid_underline = (pix_in | att_underline); + assign alpha_dots = (vid_underline & ~att_nodisp & ~blink_area) | cursorblink; + assign pix_out = (alpha_dots ^ att_inverse) & display_enable; + + // Assign intensity signal + assign intensity_out = (alpha_dots ? intensity_fg : intensity_bg) & display_enable; + + +endmodule + diff --git a/rtl/video/mda_pixel.v b/rtl/video/mda_pixel.v new file mode 100644 index 0000000..6ae4989 --- /dev/null +++ b/rtl/video/mda_pixel.v @@ -0,0 +1,126 @@ +// Graphics Gremlin +// +// Copyright (c) 2021 Eric Schlaepfer +// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +// International License. To view a copy of this license, visit +// http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative +// Commons, PO Box 1866, Mountain View, CA 94042, USA. +// +`default_nettype none +module mda_pixel( + input clk, + input[4:0] clk_seq, + input[7:0] vram_data, + input vram_read_char, + input vram_read_att, + input disp_pipeline, + input charrom_read, + input display_enable, + input cursor, + input[4:0] row_addr, + input blink_enabled, + input blink, + input video_enabled, + output video, + output intensity + ); + + reg[7:0] attr_byte; + reg[7:0] char_byte; + reg[7:0] char_byte_old; + reg[7:0] attr_byte_del; + reg[7:0] charbits; + reg[1:0] cursor_del; + reg[1:0] display_enable_del; + reg pix; + reg pix_delay; + reg ninth_column; + wire[11:0] rom_addr; + + // Character ROM + reg[7:0] char_rom[0:4095]; + initial $readmemh("mda.hex", char_rom, 0, 4095); + + + // Latch character and attribute data from VRAM + // at appropriate times + always @ (posedge clk) + begin + if (vram_read_char) begin + char_byte <= vram_data; //ES testing + char_byte_old <= char_byte; + end + if (vram_read_att) begin + attr_byte <= vram_data; //ES testing + end + end + + // Add a pipeline delay to the attribute byte data, cursor, and display + // enable so they line up with the displayed character + always @ (posedge clk) + begin + if (disp_pipeline) begin + attr_byte_del <= video_enabled ? attr_byte : 8'd0; + display_enable_del <= {display_enable_del[0], display_enable}; + cursor_del <= {cursor_del[0], cursor}; + end + end + + // Look up character byte in our character ROM table + assign rom_addr = {row_addr[3], char_byte, row_addr[2:0]}; + always @ (posedge clk) + begin + // Only load character bits at this point + if (charrom_read) begin + charbits <= char_rom[rom_addr]; + end + end + + // Pixel shifter + always @ (*) + begin + case (clk_seq[4:1]) + 5'd0: pix <= charbits[0]; + 5'd1: pix <= ninth_column; + 5'd2: pix <= charbits[7]; + 5'd3: pix <= charbits[6]; + 5'd4: pix <= charbits[5]; + 5'd5: pix <= charbits[4]; + 5'd6: pix <= charbits[3]; + 5'd7: pix <= charbits[2]; + 5'd8: pix <= charbits[1]; + default: pix <= 0; + endcase + end + + // For some characters, duplicate the 8th column as the 9th column + // (Mainly line drawing characters so they span the whole cell) + always @ (posedge clk) + begin + if (charrom_read) begin + ninth_column <= (char_byte_old[7:5] == 3'b110) ? charbits[0] : 0; + end + end + + // Add one clk cycle delay to match up pixel data with attribute byte + // data. + always @ (posedge clk) + begin + pix_delay <= pix; + end + + // Applies video attributes, generates final video + mda_attrib attrib ( + .clk(clk), + .att_byte(attr_byte_del), + .row_addr(row_addr), + .display_enable(display_enable_del[1]), + .blink_enabled(blink_enabled), + .blink(blink), + .cursor(cursor_del[1]), + .pix_in(pix_delay), + .pix_out(video), + .intensity_out(intensity) + ); + +endmodule diff --git a/rtl/video/mda_sequencer.v b/rtl/video/mda_sequencer.v new file mode 100644 index 0000000..0b1b04a --- /dev/null +++ b/rtl/video/mda_sequencer.v @@ -0,0 +1,62 @@ +// Graphics Gremlin +// +// Copyright (c) 2021 Eric Schlaepfer +// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +// International License. To view a copy of this license, visit +// http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative +// Commons, PO Box 1866, Mountain View, CA 94042, USA. +// +`default_nettype none +module mda_sequencer( + input clk, + output[4:0] clk_seq, + output vram_read, + output vram_read_a0, + output vram_read_char, + output vram_read_att, + output crtc_clk, + output charrom_read, + output disp_pipeline, + output isa_op_enable + ); + + parameter MDA_70HZ = 0; + + reg crtc_clk_int = 1'b0; + reg[4:0] clkdiv = 5'b0; + + // Sequencer: times internal operations + always @ (posedge clk) + begin + if (clkdiv == 5'd17) begin + clkdiv <= 5'd0; + crtc_clk_int <= 1'b1; + end else begin + clkdiv <= clkdiv + 1; + crtc_clk_int <= 1'b0; + end + end + + // Control signals based on the sequencer state + assign vram_read = ((clkdiv == 5'd1) || (clkdiv == 5'd2) || (clkdiv == 5'd3) + || (clkdiv == 5'd4)); + assign vram_read_a0 = (clkdiv == 5'd3); + assign vram_read_char = (clkdiv == 5'd3); + assign vram_read_att = (clkdiv == 5'd4); + assign charrom_read = (clkdiv == 5'd1); + assign disp_pipeline = (clkdiv == 5'd4); + assign crtc_clk = crtc_clk_int; + assign clk_seq = clkdiv; + // Leave a gap of at least 2 cycles between the end of ISA operation and + // vram_read. This is because an ISA operation takes 3 cycles. + // Stupid hack: 70Hz needs an extra cycle. 50Hz can't tolerate + // an extra cycle. +// if (MDA_70HZ) begin +// assign isa_op_enable = (clkdiv > 5'd6) && (clkdiv < 5'd16); +// end else begin + assign isa_op_enable = (clkdiv > 5'd5) && (clkdiv < 5'd16); +// end + + +endmodule + diff --git a/rtl/video/mda_vgaport.v b/rtl/video/mda_vgaport.v new file mode 100644 index 0000000..bfabe89 --- /dev/null +++ b/rtl/video/mda_vgaport.v @@ -0,0 +1,50 @@ +// Graphics Gremlin +// +// Copyright (c) 2021 Eric Schlaepfer +// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +// International License. To view a copy of this license, visit +// http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative +// Commons, PO Box 1866, Mountain View, CA 94042, USA. +// +module mda_vgaport( + input wire clk, + + input wire video, + input wire intensity, + + // Analog outputs + output reg [5:0] red, + output reg [5:0] green, + output reg [5:0] blue, + input wire [2:0] mda_rgb + ); + + always @(posedge clk) + begin + case({video, intensity}) // 1 = green, 2 = amber, 3 = b&w + 2'd0: begin + red <= 6'd0; + green <= 6'd0; + blue <= 6'd0; + end + 2'd1: begin + red <= mda_rgb == 0 ? 6'd0 : 6'd16; + green <= mda_rgb == 1 ? 6'd12 : 6'd16; + blue <= mda_rgb == 2 ? 6'd16 : 6'd0; + end + 2'd2: begin + red <= mda_rgb == 0 ? 6'd0 : 6'd48; + green <= mda_rgb == 1 ? 6'd21 : 6'd48; + blue <= mda_rgb == 2 ? 6'd48 : 6'd0; + end + 2'd3: begin + red <= mda_rgb == 0 ? 6'd0 : 6'd63; + green <= mda_rgb == 1 ? 6'd27 : 6'd63; + blue <= mda_rgb == 2 ? 6'd63 : 6'd0; + end + default: ; + endcase + end +endmodule + + diff --git a/rtl/video/splash.hex b/rtl/video/splash.hex index c6381cc..25e1884 100644 --- a/rtl/video/splash.hex +++ b/rtl/video/splash.hex @@ -1 +1 @@ -20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 2A 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 20 07 20 07 60 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 5C 07 20 07 29 07 20 07 20 07 2A 07 20 07 20 07 20 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 5C 07 20 07 29 07 20 07 20 07 28 07 20 07 20 07 20 07 28 07 20 07 2F 07 28 07 20 07 20 07 20 07 2A 07 20 07 20 07 20 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 5C 07 29 07 29 07 28 07 20 07 20 07 28 07 20 07 28 07 28 07 29 07 2F 07 28 07 60 07 20 07 29 07 20 07 20 07 2F 07 28 07 20 07 20 07 28 07 20 07 20 07 28 07 20 07 20 07 20 07 20 07 28 07 28 07 29 07 2F 07 28 07 20 07 20 07 29 07 5C 07 20 07 20 07 29 07 5C 07 28 07 29 07 29 07 60 07 20 07 29 07 20 07 20 07 2F 07 28 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 28 07 5F 07 29 07 28 07 29 07 5C 07 20 07 29 07 5C 07 20 07 2F 07 28 07 5F 07 29 07 29 07 28 07 20 07 29 07 28 07 5F 07 29 07 29 07 29 07 29 07 5C 07 20 07 29 07 28 07 20 07 20 07 20 07 20 07 2F 07 28 07 5F 07 29 07 7C 07 28 07 28 07 5F 07 29 07 28 07 28 07 5F 07 29 07 5C 07 20 07 20 07 28 07 20 07 29 07 28 07 5F 07 29 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 5F 07 28 07 29 07 28 07 28 07 5F 07 7C 07 28 07 5F 07 7C 07 5F 07 29 07 29 07 20 07 28 07 5F 07 28 07 5F 07 28 07 29 07 29 07 2F 07 28 07 28 07 5F 07 7C 07 28 07 29 07 5C 07 20 07 20 07 28 07 5F 07 29 07 29 07 20 07 29 07 5C 07 5F 07 5F 07 5F 07 5F 07 5F 07 28 07 28 07 5F 07 29 07 28 07 5F 07 28 07 5F 07 28 07 29 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 7C 07 20 07 20 07 5C 07 2F 07 20 07 20 07 7C 07 28 07 5F 07 29 07 20 07 5F 07 5F 07 7C 07 7C 07 5F 07 20 07 20 07 20 07 5F 07 28 07 5F 07 29 07 29 07 20 07 20 07 28 07 28 07 5F 07 29 07 20 07 7C 07 20 07 5F 07 20 07 28 07 28 07 2F 07 20 07 5F 07 5F 07 5C 07 20 07 5C 07 2F 07 20 07 2F 07 7C 07 5F 07 20 07 20 07 20 07 5F 07 7C 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 7C 07 20 07 7C 07 5C 07 2F 07 7C 07 20 07 7C 07 7C 07 20 07 5C 07 5F 07 5F 07 20 07 5C 07 20 07 20 07 7C 07 20 07 7C 07 20 07 2F 07 20 07 2D 07 5F 07 29 07 7C 07 20 07 27 07 5F 07 7C 07 20 07 7C 07 20 07 20 07 5F 07 2F 07 7C 07 20 07 28 07 5F 07 5F 07 20 07 3E 07 20 07 20 07 3C 07 20 07 20 07 20 07 7C 07 20 07 7C 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 20 07 7C 07 5F 07 7C 07 7C 07 5F 07 7C 07 5F 07 5F 07 5F 07 2F 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 5C 07 5F 07 5F 07 5F 07 7C 07 7C 07 5F 07 7C 07 20 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 20 07 20 07 5C 07 5F 07 5F 07 5F 07 2F 07 5F 07 2F 07 5C 07 5F 07 5C 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 20 07 30 07 37 07 2F 07 30 07 36 07 2F 07 32 07 30 07 32 07 32 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 50 07 6F 07 72 07 74 07 20 07 62 07 79 07 20 07 40 07 73 07 70 07 61 07 72 07 6B 07 32 07 6B 07 30 07 36 07 2C 07 20 07 40 07 6E 07 61 07 65 07 6C 07 6F 07 6F 07 62 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 50 07 6F 07 77 07 65 07 72 07 65 07 64 07 20 07 62 07 79 07 20 07 4B 07 46 07 50 07 43 07 2D 07 58 07 54 07 20 07 26 07 20 07 4D 07 43 07 4C 07 38 07 36 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 43 07 6F 07 6E 07 74 07 72 07 69 07 62 07 75 07 74 07 6F 07 72 07 73 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 40 07 4A 07 61 07 73 07 6F 07 6E 07 41 07 2C 07 20 07 40 07 67 07 79 07 75 07 72 07 63 07 6F 07 2C 07 20 07 40 07 6B 07 69 07 74 07 75 07 6E 07 65 07 2D 07 73 07 61 07 6E 07 2C 07 20 07 40 07 4D 07 69 07 63 07 72 07 6F 07 43 07 6F 07 72 07 65 07 4C 07 61 07 62 07 73 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 \ No newline at end of file +20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 2A 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 20 07 20 07 60 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 5C 07 20 07 29 07 20 07 20 07 2A 07 20 07 20 07 20 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 5C 07 20 07 29 07 20 07 20 07 28 07 20 07 20 07 20 07 28 07 20 07 2F 07 28 07 20 07 20 07 20 07 2A 07 20 07 20 07 20 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 29 07 5C 07 29 07 29 07 28 07 20 07 20 07 28 07 20 07 28 07 28 07 29 07 2F 07 28 07 60 07 20 07 29 07 20 07 20 07 2F 07 28 07 20 07 20 07 28 07 20 07 20 07 28 07 20 07 20 07 20 07 20 07 28 07 28 07 29 07 2F 07 28 07 20 07 20 07 29 07 5C 07 20 07 20 07 29 07 5C 07 28 07 29 07 29 07 60 07 20 07 29 07 20 07 20 07 2F 07 28 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 28 07 5F 07 29 07 28 07 29 07 5C 07 20 07 29 07 5C 07 20 07 2F 07 28 07 5F 07 29 07 29 07 28 07 20 07 29 07 28 07 5F 07 29 07 29 07 29 07 29 07 5C 07 20 07 29 07 28 07 20 07 20 07 20 07 20 07 2F 07 28 07 5F 07 29 07 7C 07 28 07 28 07 5F 07 29 07 28 07 28 07 5F 07 29 07 5C 07 20 07 20 07 28 07 20 07 29 07 28 07 5F 07 29 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 28 07 5F 07 28 07 29 07 28 07 28 07 5F 07 7C 07 28 07 5F 07 7C 07 5F 07 29 07 29 07 20 07 28 07 5F 07 28 07 5F 07 28 07 29 07 29 07 2F 07 28 07 28 07 5F 07 7C 07 28 07 29 07 5C 07 20 07 20 07 28 07 5F 07 29 07 29 07 20 07 29 07 5C 07 5F 07 5F 07 5F 07 5F 07 5F 07 28 07 28 07 5F 07 29 07 28 07 5F 07 28 07 5F 07 28 07 29 07 29 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 7C 07 20 07 20 07 5C 07 2F 07 20 07 20 07 7C 07 28 07 5F 07 29 07 20 07 5F 07 5F 07 7C 07 7C 07 5F 07 20 07 20 07 20 07 5F 07 28 07 5F 07 29 07 29 07 20 07 20 07 28 07 28 07 5F 07 29 07 20 07 7C 07 20 07 5F 07 20 07 28 07 28 07 2F 07 20 07 5F 07 5F 07 5C 07 20 07 5C 07 2F 07 20 07 2F 07 7C 07 5F 07 20 07 20 07 20 07 5F 07 7C 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 7C 07 20 07 7C 07 5C 07 2F 07 7C 07 20 07 7C 07 7C 07 20 07 5C 07 5F 07 5F 07 20 07 5C 07 20 07 20 07 7C 07 20 07 7C 07 20 07 2F 07 20 07 2D 07 5F 07 29 07 7C 07 20 07 27 07 5F 07 7C 07 20 07 7C 07 20 07 20 07 5F 07 2F 07 7C 07 20 07 28 07 5F 07 5F 07 20 07 3E 07 20 07 20 07 3C 07 20 07 20 07 20 07 7C 07 20 07 7C 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 20 07 7C 07 5F 07 7C 07 7C 07 5F 07 7C 07 5F 07 5F 07 5F 07 2F 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 5C 07 5F 07 5F 07 5F 07 7C 07 7C 07 5F 07 7C 07 20 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 20 07 20 07 5C 07 5F 07 5F 07 5F 07 2F 07 5F 07 2F 07 5C 07 5F 07 5C 07 20 07 20 07 7C 07 5F 07 7C 07 20 07 20 07 31 07 33 07 2F 07 30 07 36 07 2F 07 32 07 30 07 32 07 32 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 50 07 6F 07 72 07 74 07 20 07 62 07 79 07 20 07 40 07 73 07 70 07 61 07 72 07 6B 07 32 07 6B 07 30 07 36 07 2C 07 20 07 40 07 6E 07 61 07 65 07 6C 07 6F 07 6F 07 62 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 50 07 6F 07 77 07 65 07 72 07 65 07 64 07 20 07 62 07 79 07 20 07 4B 07 46 07 50 07 43 07 2D 07 58 07 54 07 20 07 26 07 20 07 4D 07 43 07 4C 07 38 07 36 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 43 07 6F 07 6E 07 74 07 72 07 69 07 62 07 75 07 74 07 6F 07 72 07 73 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 2D 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 40 07 4A 07 61 07 73 07 6F 07 6E 07 41 07 2C 07 20 07 40 07 67 07 79 07 75 07 72 07 63 07 6F 07 2C 07 20 07 40 07 6B 07 69 07 74 07 75 07 6E 07 65 07 2D 07 73 07 61 07 6E 07 2C 07 20 07 40 07 4D 07 69 07 63 07 72 07 6F 07 43 07 6F 07 72 07 65 07 4C 07 61 07 62 07 73 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 20 07 \ No newline at end of file diff --git a/sys/ascal.vhd b/sys/ascal.vhd index bd4e238..9b3465e 100644 --- a/sys/ascal.vhd +++ b/sys/ascal.vhd @@ -113,21 +113,23 @@ USE ieee.numeric_std.ALL; ENTITY ascal IS GENERIC ( - MASK : unsigned(7 DOWNTO 0) :=x"FF"; - RAMBASE : unsigned(31 DOWNTO 0); - RAMSIZE : unsigned(31 DOWNTO 0) := x"0080_0000"; -- =8MB - INTER : boolean := true; - HEADER : boolean := true; - DOWNSCALE : boolean := true; - BYTESWAP : boolean := true; - PALETTE : boolean := true; - PALETTE2 : boolean := true; - FRAC : natural RANGE 4 TO 6 :=4; - OHRES : natural RANGE 1 TO 4096 :=2048; - IHRES : natural RANGE 1 TO 2048 :=2048; - N_DW : natural RANGE 64 TO 128 := 128; - N_AW : natural RANGE 8 TO 32 := 32; - N_BURST : natural := 256 -- 256 bytes per burst + MASK : unsigned(7 DOWNTO 0) :=x"FF"; + RAMBASE : unsigned(31 DOWNTO 0); + RAMSIZE : unsigned(31 DOWNTO 0) := x"0080_0000"; -- =8MB + INTER : boolean := true; + HEADER : boolean := true; + DOWNSCALE : boolean := true; + BYTESWAP : boolean := true; + PALETTE : boolean := true; + PALETTE2 : boolean := true; + ADAPTIVE : boolean := true; + DOWNSCALE_NN : boolean := false; + FRAC : natural RANGE 4 TO 8 :=4; + OHRES : natural RANGE 1 TO 4096 :=2048; + IHRES : natural RANGE 1 TO 2048 :=2048; + N_DW : natural RANGE 64 TO 128 := 128; + N_AW : natural RANGE 8 TO 32 := 32; + N_BURST : natural := 256 -- 256 bytes per burst ); PORT ( ------------------------------------ @@ -225,12 +227,12 @@ ENTITY ascal IS ------------------------------------ -- Polyphase filter coefficients -- Order : - -- [Horizontal] [Vertical] + -- [Horizontal] [Vertical] [Horizontal2] [Vertical2] -- [0]...[2**FRAC-1] -- [-1][0][1][2] poly_clk : IN std_logic; - poly_dw : IN unsigned(8 DOWNTO 0); - poly_a : IN unsigned(FRAC+2 DOWNTO 0); + poly_dw : IN unsigned(9 DOWNTO 0); + poly_a : IN unsigned(FRAC+3 DOWNTO 0); poly_wr : IN std_logic; ------------------------------------ @@ -295,6 +297,7 @@ ARCHITECTURE rtl OF ascal IS r,g,b : unsigned(7 DOWNTO 0); -- 0.8 END RECORD; TYPE arr_pix IS ARRAY (natural RANGE <>) OF type_pix; + TYPE arr_pixq IS ARRAY(natural RANGE <>) OF arr_pix(0 TO 3); ATTRIBUTE ramstyle : string; SUBTYPE uint12 IS natural RANGE 0 TO 4095; @@ -302,9 +305,11 @@ ARCHITECTURE rtl OF ascal IS TYPE arr_uv48 IS ARRAY (natural RANGE <>) OF unsigned(47 DOWNTO 0); TYPE arr_uv24 IS ARRAY (natural RANGE <>) OF unsigned(23 DOWNTO 0); - TYPE arr_uv36 IS ARRAY (natural RANGE <>) OF unsigned(35 DOWNTO 0); + TYPE arr_uv40 IS ARRAY (natural RANGE <>) OF unsigned(39 DOWNTO 0); TYPE arr_int9 IS ARRAY (natural RANGE <>) OF integer RANGE -256 TO 255; TYPE arr_uint12 IS ARRAY (natural RANGE <>) OF uint12; + TYPE arr_frac IS ARRAY (natural RANGE <>) OF unsigned(11 DOWNTO 0); + TYPE arr_div IS ARRAY (natural RANGE <>) OF unsigned(20 DOWNTO 0); ---------------------------------------------------------- -- Input image @@ -415,7 +420,7 @@ ARCHITECTURE rtl OF ascal IS ATTRIBUTE ramstyle of pal1_mem : signal is "no_rw_check"; ATTRIBUTE ramstyle of pal2_mem : signal is "no_rw_check"; SIGNAL o_htotal,o_hsstart,o_hsend : uint12; - SIGNAL o_hmin,o_hmax,o_hdisp : uint12; + SIGNAL o_hmin,o_hmax,o_hdisp,o_v_hmin_adj : uint12; SIGNAL o_hsize,o_vsize : uint12; SIGNAL o_vtotal,o_vsstart,o_vsend : uint12; SIGNAL o_vmin,o_vmax,o_vdisp : uint12; @@ -430,7 +435,7 @@ ARCHITECTURE rtl OF ascal IS SIGNAL o_pshift : natural RANGE 0 TO 15; SIGNAL o_readack,o_readack_sync,o_readack_sync2 : std_logic; SIGNAL o_readdataack,o_readdataack_sync,o_readdataack_sync2 : std_logic; - SIGNAL o_copyv : unsigned(0 TO 8); + SIGNAL o_copyv : unsigned(0 TO 14); SIGNAL o_adrs : unsigned(31 DOWNTO 0); -- Avalon address SIGNAL o_adrs_pre : natural RANGE 0 TO 2**24-1; SIGNAL o_stride : unsigned(13 DOWNTO 0); @@ -448,16 +453,19 @@ ARCHITECTURE rtl OF ascal IS ATTRIBUTE ramstyle OF o_line1 : SIGNAL IS "no_rw_check"; ATTRIBUTE ramstyle OF o_line2 : SIGNAL IS "no_rw_check"; ATTRIBUTE ramstyle OF o_line3 : SIGNAL IS "no_rw_check"; - SIGNAL o_wadl,o_radl : natural RANGE 0 TO OHRES-1; + SIGNAL o_wadl,o_radl0,o_radl1,o_radl2,o_radl3 : natural RANGE 0 TO OHRES-1; SIGNAL o_ldw,o_ldr0,o_ldr1,o_ldr2,o_ldr3 : type_pix; SIGNAL o_wr : unsigned(3 DOWNTO 0); SIGNAL o_hcpt,o_vcpt,o_vcpt_pre,o_vcpt_pre2,o_vcpt_pre3 : uint12; SIGNAL o_ihsize,o_ihsizem,o_ivsize : uint12; SIGNAL o_ihsize_temp, o_ihsize_temp2 : natural RANGE 0 TO 32767; - SIGNAL o_vfrac,o_hfrac,o_hfrac1,o_hfrac2,o_hfrac3,o_hfrac4 : unsigned(11 DOWNTO 0); + SIGNAL o_vfrac : unsigned(11 DOWNTO 0); + SIGNAL o_hfrac : arr_frac(0 TO 9); + ATTRIBUTE ramstyle OF o_hfrac : SIGNAL IS "logic"; -- avoid blockram shift register + SIGNAL o_hacc,o_hacc_ini,o_hacc_next,o_vacc,o_vacc_next,o_vacc_ini : natural RANGE 0 TO 4*OHRES-1; - SIGNAL o_hsv,o_vsv,o_dev,o_pev,o_end : unsigned(0 TO 5); + SIGNAL o_hsv,o_vsv,o_dev,o_pev,o_end : unsigned(0 TO 11); SIGNAL o_hsp,o_vss : std_logic; SIGNAL o_vcarrym,o_prim : boolean; SIGNAL o_read,o_read_pre : std_logic; @@ -474,14 +482,20 @@ ARCHITECTURE rtl OF ascal IS TYPE arr_uint4 IS ARRAY (natural RANGE <>) OF natural RANGE 0 TO 15; SIGNAL o_off : arr_uint4(0 TO 2); SIGNAL o_bibu : std_logic :='0'; - SIGNAL o_dcptv : arr_uint12(1 TO 8); + SIGNAL o_dcptv : arr_uint12(1 TO 14); SIGNAL o_dcpt : uint12; SIGNAL o_hpixs,o_hpix0,o_hpix1,o_hpix2,o_hpix3 : type_pix; - SIGNAL o_hpixq,o_vpixq,o_vpixq1 : arr_pix(0 TO 3); - + SIGNAL o_hpixq : arr_pixq(2 TO 8); + ATTRIBUTE ramstyle OF o_hpixq : SIGNAL IS "logic"; -- avoid blockram shift register + SIGNAL o_vpixq, o_vpixq_pre : arr_pix(0 TO 3); + SIGNAL o_vpix_outer : arr_pix(0 TO 2); + SIGNAL o_vpix_inner : arr_pix(0 TO 6); + + SIGNAL o_vpe : std_logic; - SIGNAL o_div,o_div2 : unsigned(18 DOWNTO 0); --uint12; - SIGNAL o_dir,o_dir2 : unsigned(11 DOWNTO 0); + SIGNAL o_div : arr_div(0 TO 2); --uint12; + SIGNAL o_dir : arr_frac(0 TO 2); + ATTRIBUTE ramstyle OF o_div, o_dir : SIGNAL IS "logic"; -- avoid blockram shift register SIGNAL o_vdivi : unsigned(12 DOWNTO 0); SIGNAL o_vdivr : unsigned(24 DOWNTO 0); SIGNAL o_divstart : std_logic; @@ -711,8 +725,7 @@ ARCHITECTURE rtl OF ascal IS SIGNAL o_h_near_frac,o_v_near_frac : unsigned(FRAC-1 DOWNTO 0); SIGNAL o_h_bil_frac,o_v_bil_frac : unsigned(FRAC-1 DOWNTO 0); SIGNAL o_h_bil_pix,o_v_bil_pix : type_pix; - SIGNAL o_h_near_pix,o_v_near_pix : type_pix; - + ----------------------------------------------------------------------------- -- Nearest + Bilinear + Sharp Bilinear FUNCTION bil_frac(f : unsigned) RETURN unsigned IS @@ -760,6 +773,7 @@ ARCHITECTURE rtl OF ascal IS END IF; RETURN x; END FUNCTION; + SIGNAL o_h_bil_t,o_v_bil_t : type_bil_t; SIGNAL o_h_near_t,o_v_near_t : type_bil_t; SIGNAL i_h_bil_t : type_bil_t; @@ -933,82 +947,160 @@ ARCHITECTURE rtl OF ascal IS ----------------------------------------------------------------------------- -- Polyphase - - CONSTANT POLY16 : arr_int9 := ( - -24,-21,-15,-9,-5,-1,4,8,6,8,5,4,3,1,0,0, - 176,174,169,160,150,131,115,85,58,27,4,-6,-20,-24,-26,-25, - -24,-25,-26,-24,-20,-6,4,27,58,85,115,131,150,160,169,174, - 0,0,0,1,3,4,5,8,6,8,4,-1,-5,-9,-15,-21); - - CONSTANT POLY32 : arr_int9 := ( - -24,-22,-20,-18,-16,-13,-11,-8,-6,-3,-1,0,2,3,5,5,6,6,6,5,5,4,4,3,2,1,1,0,0,0,0,0, - 176,175,174,172,169,164,160,153,147,138,129,119,109,96,84,71,58,40,22,12,3,-4,-12,-16,-20,-22,-25,-25,-26,-25,-25,-25, - -24,-25,-26,-26,-26,-24,-23,-19,-16,-10,-4,4,11,22,32,45,58,77,96,108,119,129,140,147,154,159,165,168,172,173,175,175, - 0,0,0,0,1,1,2,2,3,3,4,5,6,7,7,7,6,5,4,3,1,-1,-4,-6,-8,-10,-13,-15,-18,-20,-22,-22); - - FUNCTION init_poly RETURN arr_uv36 IS - VARIABLE m : arr_uv36(0 TO 2**FRAC-1) :=(OTHERS =>x"000000000"); - BEGIN - IF FRAC=4 THEN - FOR i IN 0 TO 15 LOOP - m(i):=unsigned(to_signed(POLY16(i),9) & to_signed(POLY16(i+16),9) & - to_signed(POLY16(i+32),9) & to_signed(POLY16(i+48),9)); - END LOOP; - ELSIF FRAC=5 THEN - FOR i IN 0 TO 31 LOOP - m(i):=unsigned(to_signed(POLY32(i),9) & to_signed(POLY32(i+32),9) & - to_signed(POLY32(i+64),9) & to_signed(POLY32(i+96),9)); - END LOOP; - END IF; - RETURN m; - END FUNCTION; - - SIGNAL o_h_poly : arr_uv36(0 TO 2**FRAC-1):=init_poly; - SIGNAL o_v_poly : arr_uv36(0 TO 2**FRAC-1):=init_poly; - ATTRIBUTE ramstyle OF o_h_poly : SIGNAL IS "no_rw_check"; - ATTRIBUTE ramstyle OF o_v_poly : SIGNAL IS "no_rw_check"; - SIGNAL o_h_poly_a,o_v_poly_a : integer RANGE 0 TO 2**FRAC-1; - SIGNAL o_h_poly_dr,o_h_poly_dr2,o_v_poly_dr,o_v_poly_dr2 : unsigned(35 DOWNTO 0); - SIGNAL o_h_poly_pix,o_v_poly_pix : type_pix; - SIGNAL poly_h_wr,poly_v_wr : std_logic; - SIGNAL poly_tdw : unsigned(35 DOWNTO 0); - SIGNAL poly_a2 : unsigned(FRAC-1 DOWNTO 0); - - TYPE type_poly_t IS RECORD - r0,r1,b0,b1,g0,g1 : signed(17 DOWNTO 0); + -- 2.7 + TYPE poly_phase_t IS RECORD + t0, t1, t2, t3 : signed(9 DOWNTO 0); + END RECORD; + + -- 4.14 + TYPE poly_phase_interp_t IS RECORD + t0, t1, t2, t3 : signed(17 DOWNTO 0); END RECORD; - SIGNAL o_h_poly_t,o_v_poly_t : type_poly_t; + -- 5.22 + TYPE type_poly_t IS RECORD + r0,r1,b0,b1,g0,g1 : signed(26 DOWNTO 0); + END RECORD; - FUNCTION poly_calc1(fi : unsigned(35 DOWNTO 0); + + SIGNAL o_h_poly_mem : arr_uv40(0 TO 2**FRAC-1); + SIGNAL o_v_poly_mem : arr_uv40(0 TO 2**FRAC-1); + SIGNAL o_a_poly_mem : arr_uv40(0 TO 2**FRAC-1); + ATTRIBUTE ramstyle OF o_h_poly_mem : SIGNAL IS "no_rw_check"; + ATTRIBUTE ramstyle OF o_v_poly_mem : SIGNAL IS "no_rw_check"; + ATTRIBUTE ramstyle OF o_a_poly_mem : SIGNAL IS "no_rw_check"; + SIGNAL o_a_poly_addr, o_v_poly_addr : integer RANGE 0 TO 2**FRAC-1; + SIGNAL o_h_poly_phase_a,o_h_poly_phase_a2,o_h_poly_phase_a3, o_h_poly_phase_a4, o_h_poly_phase_a5 : poly_phase_t; + SIGNAL o_v_poly_phase_a,o_v_poly_phase_a2,o_v_poly_phase_a3, o_v_poly_phase_a4, o_v_poly_phase_a5 : poly_phase_t; + SIGNAL o_poly_phase_a, o_poly_phase_a2, o_poly_phase_a3 : poly_phase_t; + SIGNAL o_poly_phase_b,o_poly_phase_b2,o_poly_phase_b3 : poly_phase_t; + SIGNAL o_v_poly_phase, o_v_poly_phase2, o_h_poly_phase, o_poly_phase, o_poly_phase1 : poly_phase_interp_t; + SIGNAL o_v_poly_pix, o_h_poly_pix, o_h_lum_pix, o_v_lum_pix : type_pix; + SIGNAL o_poly_lum, o_poly_lum1 : unsigned(7 DOWNTO 0); + SIGNAL o_poly_lerp_ta, o_poly_lerp_tb : signed(9 DOWNTO 0); + SIGNAL o_h_poly_t,o_h_poly_t2,o_v_poly_t : type_poly_t; + + SIGNAL o_v_poly_adaptive, o_h_poly_adaptive, o_v_poly_use_adaptive, o_h_poly_use_adaptive : std_logic; + SIGNAL poly_wr_mode : std_logic_vector(2 DOWNTO 0); + SIGNAL poly_tdw : unsigned(39 DOWNTO 0); + SIGNAL poly_a2 : unsigned(FRAC-1 DOWNTO 0); + + + FUNCTION poly_unpack(a : unsigned(39 DOWNTO 0)) RETURN poly_phase_t IS + VARIABLE v : poly_phase_t; + BEGIN + v.t0 := signed(a(39 DOWNTO 30)); + v.t1 := signed(a(29 DOWNTO 20)); + v.t2 := signed(a(19 DOWNTO 10)); + v.t3 := signed(a( 9 DOWNTO 0)); + + RETURN v; + END FUNCTION; + + -- 6 DSP 18*18 + 18*18 + FUNCTION poly_calc(fi : poly_phase_interp_t; p : arr_pix(0 TO 3)) RETURN type_poly_t IS VARIABLE t : type_poly_t; BEGIN - -- 2.7 * 1.8 = 3.15 - t.r0:=(signed(fi(35 DOWNTO 27)) * signed('0' & p(0).r) + - signed(fi(26 DOWNTO 18)) * signed('0' & p(1).r)); - t.r1:=(signed(fi(17 DOWNTO 9)) * signed('0' & p(2).r) + - signed(fi( 8 DOWNTO 0)) * signed('0' & p(3).r)); - t.g0:=(signed(fi(35 DOWNTO 27)) * signed('0' & p(0).g) + - signed(fi(26 DOWNTO 18)) * signed('0' & p(1).g)); - t.g1:=(signed(fi(17 DOWNTO 9)) * signed('0' & p(2).g) + - signed(fi( 8 DOWNTO 0)) * signed('0' & p(3).g)); - t.b0:=(signed(fi(35 DOWNTO 27)) * signed('0' & p(0).b) + - signed(fi(26 DOWNTO 18)) * signed('0' & p(1).b)); - t.b1:=(signed(fi(17 DOWNTO 9)) * signed('0' & p(2).b) + - signed(fi( 8 DOWNTO 0)) * signed('0' & p(3).b)); + -- 3.15 * 1.8 = 4.23 + t.r0:=(fi.t0 * signed('0' & p(0).r) + + fi.t1 * signed('0' & p(1).r)); + t.r1:=(fi.t2 * signed('0' & p(2).r) + + fi.t3 * signed('0' & p(3).r)); + t.g0:=(fi.t0 * signed('0' & p(0).g) + + fi.t1 * signed('0' & p(1).g)); + t.g1:=(fi.t2 * signed('0' & p(2).g) + + fi.t3 * signed('0' & p(3).g)); + t.b0:=(fi.t0 * signed('0' & p(0).b) + + fi.t1 * signed('0' & p(1).b)); + t.b1:=(fi.t2 * signed('0' & p(2).b) + + fi.t3 * signed('0' & p(3).b)); RETURN t; END FUNCTION; - FUNCTION poly_calc2(t : type_poly_t) RETURN type_pix IS + FUNCTION poly_final(t : type_poly_t) RETURN type_pix IS VARIABLE p : type_pix; BEGIN - p.r:=bound(unsigned(t.r0+t.r1),15); - p.g:=bound(unsigned(t.g0+t.g1),15); - p.b:=bound(unsigned(t.b0+t.b1),15); + p.r:=bound(unsigned(t.r0(26 DOWNTO 8)+t.r1(26 DOWNTO 8)),15); + p.g:=bound(unsigned(t.g0(26 DOWNTO 8)+t.g1(26 DOWNTO 8)),15); + p.b:=bound(unsigned(t.b0(26 DOWNTO 8)+t.b1(26 DOWNTO 8)),15); RETURN p; END FUNCTION; - + + -- 4 DSP 18*18 + 18*18 + FUNCTION poly_lerp(a : poly_phase_t; + b : poly_phase_t; + ta : SIGNED(9 DOWNTO 0); + tb : SIGNED(9 DOWNTO 0)) RETURN poly_phase_interp_t IS + VARIABLE v : poly_phase_interp_t; + VARIABLE t0,t1,t2,t3 : signed(19 DOWNTO 0); + BEGIN + -- 2.8 * 2.8 = 4.16 + t0 := (a.t0 * ta) + (b.t0 * tb); + t1 := (a.t1 * ta) + (b.t1 * tb); + t2 := (a.t2 * ta) + (b.t2 * tb); + t3 := (a.t3 * ta) + (b.t3 * tb); + + -- 4.16 -> 3.15 + v.t0 := t0(18 DOWNTO 1); + v.t1 := t1(18 DOWNTO 1); + v.t2 := t2(18 DOWNTO 1); + v.t3 := t3(18 DOWNTO 1); + + RETURN v; + END FUNCTION; + + FUNCTION poly_cvt(a : poly_phase_t) RETURN poly_phase_interp_t IS + VARIABLE v : poly_phase_interp_t; + BEGIN + v.t0 := resize(signed( a.t0 & "0000000" ), v.t0'length); + v.t1 := resize(signed( a.t1 & "0000000" ), v.t1'length); + v.t2 := resize(signed( a.t2 & "0000000" ), v.t2'length); + v.t3 := resize(signed( a.t3 & "0000000" ), v.t3'length); + RETURN v; + END FUNCTION; + + -- Nearest neighbor polyphase ceoffs + FUNCTION poly_nn(frac : unsigned(FRAC-1 DOWNTO 0)) RETURN poly_phase_t IS + VARIABLE v : poly_phase_t; + BEGIN + IF frac(frac'left)='0' THEN + v := (t1=>to_signed(256, 10), OTHERS=>to_signed(0, 10)); + ELSE + v := (t2=>to_signed(256, 10), OTHERS=>to_signed(0, 10)); + END IF; + RETURN v; + END FUNCTION; + + + FUNCTION poly_lum(p : type_pix) RETURN unsigned IS + VARIABLE v : UNSIGNED(7 DOWNTO 0); + BEGIN + -- 0.375 R + 0.5 G + 0.125 B + --v := ("00" & p.r(7 DOWNTO 2)) + ("000" & p.r(7 DOWNTO 3)) + ("0" & p.g(7 DOWNTO 1)) + ("000" & p.b(7 DOWNTO 3)); + + -- 0.25 R + 0.5 G + 0.25 B + -- v := ( ("00" & p.r(7 DOWNTO 2)) + ("0" & p.g(7 DOWNTO 1)) + ("00" & p.b(7 DOWNTO 2)) ); + + -- Just OR them all together + --v := (p.r OR p.g OR p.b); + + -- Maximum + IF p.r > p.g THEN + v := p.r; + ELSE + v := p.g; + END IF; + + IF p.b > v THEN + v := p.b; + END IF; + + -- 100% + -- v := "1111111"; + + RETURN v; + END FUNCTION; BEGIN ----------------------------------------------------------------------------- @@ -1160,7 +1252,7 @@ BEGIN i_format<=format; -- -- Downscaling : Nearest or bilinear - i_bil<=to_std_logic(i_mode(2 DOWNTO 0)/="000" AND DOWNSCALE); + i_bil<=to_std_logic(i_mode(2 DOWNTO 0)/="000" AND NOT DOWNSCALE_NN); i_hdown<=to_std_logic(i_hsize>i_ohsize AND DOWNSCALE); --H downscale i_vdown<=to_std_logic(i_vsize>i_ovsize AND DOWNSCALE); --V downscale @@ -1272,11 +1364,12 @@ BEGIN -- C4 : Horizontal Bilinear IF i_bil='0' THEN frac_v:=near_frac(i_h_frac); + i_h_bil_t<=near_calc(frac_v,(i_hpix2,i_hpix2,i_hpix3,i_hpix3)); ELSE frac_v:=bil_frac(i_h_frac); + i_h_bil_t<=bil_calc(frac_v,(i_hpix2,i_hpix2,i_hpix3,i_hpix3)); END IF; - i_h_bil_t<=bil_calc(frac_v,(i_hpix2,i_hpix2,i_hpix3,i_hpix3)); i_hpix.r<=bound(i_h_bil_t.r,8+FRAC); i_hpix.g<=bound(i_h_bil_t.g,8+FRAC); i_hpix.b<=bound(i_h_bil_t.b,8+FRAC); @@ -1288,11 +1381,12 @@ BEGIN -- C5 : Vertical Bilinear IF i_bil='0' THEN frac_v:=near_frac(i_v_frac(11 DOWNTO 0)); + bil_t_v:=near_calc(frac_v,(i_hpix,i_hpix,i_ldrm,i_ldrm)); ELSE frac_v:=bil_frac(i_v_frac(11 DOWNTO 0)); + bil_t_v:=bil_calc(frac_v,(i_hpix,i_hpix,i_ldrm,i_ldrm)); END IF; - bil_t_v:=bil_calc(frac_v,(i_hpix,i_hpix,i_ldrm,i_ldrm)); i_pix.r<=bound(bil_t_v.r,8+FRAC); i_pix.g<=bound(bil_t_v.g,8+FRAC); i_pix.b<=bound(bil_t_v.b,8+FRAC); @@ -1721,7 +1815,7 @@ BEGIN VARIABLE hcarry_v,vcarry_v : boolean; VARIABLE dif_v : natural RANGE 0 TO 8*OHRES-1; VARIABLE off_v : natural RANGE 0 TO 15; - BEGIN + BEGIN IF o_reset_na='0' THEN o_copy<=sWAIT; o_state<=sDISP; @@ -1822,7 +1916,14 @@ BEGIN o_vdown<='0'; END IF; - o_ihsize_temp <= o_ihsize * to_integer(o_format(2 DOWNTO 0) - 2); + -- 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp + CASE o_format(2 DOWNTO 0) IS + WHEN "011" => o_ihsize_temp <= o_ihsize; + WHEN "100" => o_ihsize_temp <= o_ihsize * 2; + WHEN "110" => o_ihsize_temp <= o_ihsize * 4; + WHEN OTHERS => o_ihsize_temp <= o_ihsize * 3; + END CASE; + o_ihsize_temp2 <= (o_ihsize_temp + N_BURST - 1); o_hburst <= o_ihsize_temp2 / N_BURST; @@ -2111,7 +2212,7 @@ BEGIN o_hpix1<=o_hpix0; o_hpix2<=o_hpix1; o_hpix3<=o_hpix2; - + IF o_first='1' THEN -- Left edge. Duplicate first pixel o_hpix1<=hpix_v; @@ -2171,13 +2272,87 @@ BEGIN ------------------------------------------------------ END IF; END PROCESS Scalaire; - - o_h_poly_a<=to_integer(o_hfrac1(11 DOWNTO 12-FRAC)); - o_v_poly_a<=to_integer(o_vfrac(11 DOWNTO 12-FRAC)); - - o_h_poly_dr<=o_h_poly(o_h_poly_a) WHEN rising_edge(o_clk); - o_v_poly_dr<=o_v_poly(o_v_poly_a) WHEN rising_edge(o_clk); - + + -- Fetch polyphase coefficients + PolyFetch:PROCESS (o_clk) IS + VARIABLE hfrac3_v, vfrac_v : unsigned(FRAC-1 DOWNTO 0); + BEGIN + IF rising_edge(o_clk) THEN + hfrac3_v:=o_hfrac(3)(11 DOWNTO 12-FRAC); + vfrac_v:=o_vfrac(11 DOWNTO 12-FRAC); + + o_v_poly_use_adaptive <= to_std_logic((o_vmode(2 DOWNTO 0)/="000") AND (o_v_poly_adaptive = '1')); + o_h_poly_use_adaptive <= to_std_logic((o_hmode(2 DOWNTO 0)/="000") AND (o_h_poly_adaptive = '1')); + o_v_poly_addr<=to_integer(o_vfrac(11 DOWNTO 12-FRAC)); + + -- C3 / HC3 / VC4 + IF o_vmode(2 DOWNTO 0)/="000" THEN + o_v_poly_phase_a<=poly_unpack(o_v_poly_mem(o_v_poly_addr)); + ELSE + o_v_poly_phase_a<=poly_nn(vfrac_v); + END IF; + + IF o_hmode(2 DOWNTO 0)/="000" THEN + o_h_poly_phase_a<=poly_unpack(o_h_poly_mem(to_integer(hfrac3_v))); + ELSE + o_h_poly_phase_a<=poly_nn(hfrac3_v); + END IF; + + IF o_v_poly_use_adaptive='1' THEN + o_poly_lum<=poly_lum(o_v_lum_pix); + o_a_poly_addr<=o_v_poly_addr; + ELSIF o_h_poly_use_adaptive='1' THEN + o_poly_lum<=poly_lum(o_h_lum_pix); + o_a_poly_addr<=to_integer(hfrac3_v); + END IF; + + -- C4 / HC4 / VC5 + o_poly_phase_b<=poly_unpack(o_a_poly_mem(o_a_poly_addr)); + + IF o_v_poly_use_adaptive='1' THEN + o_poly_phase_a<=o_v_poly_phase_a; + ELSIF o_h_poly_use_adaptive = '1' THEN + o_poly_phase_a<=o_h_poly_phase_a; + END IF; + + o_h_poly_phase_a2<=o_h_poly_phase_a; + o_v_poly_phase_a2<=o_v_poly_phase_a; + o_poly_lum1<=o_poly_lum; + + -- C5 / HC5 / VC6 + o_poly_lerp_ta<=signed(to_unsigned(256,10) - resize(o_poly_lum1,10)); + o_poly_lerp_tb<=signed(resize(o_poly_lum1,10)); + + o_poly_phase_b2<=o_poly_phase_b; + o_poly_phase_a2<=o_poly_phase_a; + + o_h_poly_phase_a3<=o_h_poly_phase_a2; + o_v_poly_phase_a3<=o_v_poly_phase_a2; + + -- C6 / HC6 / VC7 + o_poly_phase<=poly_lerp(o_poly_phase_a2, o_poly_phase_b2, o_poly_lerp_ta, o_poly_lerp_tb); + o_h_poly_phase_a4<=o_h_poly_phase_a3; + o_v_poly_phase_a4<=o_v_poly_phase_a3; + + -- C7 / HC7 / VC8 + o_h_poly_phase_a5<=o_h_poly_phase_a4; + o_v_poly_phase_a5<=o_v_poly_phase_a4; + o_poly_phase1<=o_poly_phase; + + -- C8 / HC8 / VC9 + o_v_poly_phase<=poly_cvt(o_v_poly_phase_a5); + o_h_poly_phase<=poly_cvt(o_h_poly_phase_a5); + + IF o_v_poly_use_adaptive = '1' THEN + o_v_poly_phase<=o_poly_phase1; + ELSIF o_h_poly_use_adaptive = '1' THEN + o_h_poly_phase<=o_poly_phase1; + END IF; + + END IF; + END PROCESS PolyFetch; + + -- Framebuffer palette GenPal1:IF PALETTE GENERATE Tempera1:PROCESS(pal1_clk) IS @@ -2224,172 +2399,197 @@ BEGIN BEGIN IF rising_edge(poly_clk) THEN IF poly_wr='1' THEN - poly_tdw(8+9*(3-to_integer(poly_a(1 DOWNTO 0))) DOWNTO - 9*(3-to_integer(poly_a(1 DOWNTO 0))))<=poly_dw; + poly_tdw(9+10*(3-to_integer(poly_a(1 DOWNTO 0))) DOWNTO + 10*(3-to_integer(poly_a(1 DOWNTO 0))))<=poly_dw; END IF; - poly_h_wr<=poly_wr AND NOT poly_a(FRAC+2); - poly_v_wr<=poly_wr AND poly_a(FRAC+2); + poly_wr_mode(0)<=poly_wr AND NOT poly_a(FRAC+2); + poly_wr_mode(1)<=poly_wr AND poly_a(FRAC+2); + poly_wr_mode(2)<=poly_wr AND poly_a(FRAC+3) AND to_std_logic(ADAPTIVE); poly_a2<=poly_a(FRAC+1 DOWNTO 2); - IF poly_h_wr='1' THEN - o_h_poly(to_integer(poly_a2))<=poly_tdw; - END IF; - IF poly_v_wr='1' THEN - o_v_poly(to_integer(poly_a2))<=poly_tdw; - END IF; + CASE poly_wr_mode IS + WHEN "001" => -- horiz + o_h_poly_mem(to_integer(poly_a2))<=poly_tdw; + o_h_poly_adaptive<='0'; + WHEN "010" => -- vert + o_v_poly_mem(to_integer(poly_a2))<=poly_tdw; + o_v_poly_adaptive<='0'; + WHEN "101" => -- horiz adaptive + o_a_poly_mem(to_integer(poly_a2))<=poly_tdw; + o_h_poly_adaptive<='1'; + WHEN "110" => -- vert adaptive + o_a_poly_mem(to_integer(poly_a2))<=poly_tdw; + o_v_poly_adaptive<='1'; + WHEN OTHERS => NULL; + END CASE; END IF; END PROCESS Polikarpov; ----------------------------------------------------------------------------- -- Horizontal Scaler HSCAL:PROCESS(o_clk) IS - VARIABLE div_v : unsigned(18 DOWNTO 0); + VARIABLE div_v : unsigned(20 DOWNTO 0); VARIABLE dir_v : unsigned(11 DOWNTO 0); BEGIN IF rising_edge(o_clk) THEN -- Pipeline signals ----------------------------------- - -- Pipelined 6 bits non-restoring divider. Cycle 1 + -- Pipelined 8 bits non-restoring divider. Cycle 1 dir_v:=x"000"; - div_v:=to_unsigned(o_hacc * 64,19); + div_v:=to_unsigned(o_hacc * 256,21); - div_v:=div_v-to_unsigned(o_hsize*64,19); - dir_v(11):=NOT div_v(18); - IF div_v(18)='0' THEN - div_v:=div_v-to_unsigned(o_hsize*32,19); + div_v:=div_v-to_unsigned(o_hsize*256,21); + dir_v(11):=NOT div_v(20); + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*128,21); ELSE - div_v:=div_v+to_unsigned(o_hsize*32,19); + div_v:=div_v+to_unsigned(o_hsize*128,21); END IF; - dir_v(10):=NOT div_v(18); - o_div<=div_v; - o_dir<=dir_v; + dir_v(10):=NOT div_v(20); + + o_div(0)<=div_v; + o_dir(0)<=dir_v; -- Cycle 2 - div_v:=o_div; - dir_v:=o_dir; - IF div_v(18)='0' THEN - div_v:=div_v-to_unsigned(o_hsize*16,19); + div_v:=o_div(0); + dir_v:=o_dir(0); + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*64,21); ELSE - div_v:=div_v+to_unsigned(o_hsize*16,19); + div_v:=div_v+to_unsigned(o_hsize*64,21); END IF; - dir_v( 9):=NOT div_v(18); + dir_v( 9):=NOT div_v(20); - IF div_v(18)='0' THEN - div_v:=div_v-to_unsigned(o_hsize*8,19); + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*32,21); ELSE - div_v:=div_v+to_unsigned(o_hsize*8,19); + div_v:=div_v+to_unsigned(o_hsize*32,21); END IF; - dir_v(8):=NOT div_v(18); - o_div2<=div_v; - o_dir2<=dir_v; - + dir_v( 8):=NOT div_v(20); + + o_div(1)<=div_v; + o_dir(1)<=dir_v; + -- Cycle 3 - div_v:=o_div2; - dir_v:=o_dir2; + div_v:=o_div(1); + dir_v:=o_dir(1); IF FRAC>4 THEN - IF div_v(18)='0' THEN - div_v:=div_v-to_unsigned(o_hsize*4,19); + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*16,21); ELSE - div_v:=div_v+to_unsigned(o_hsize*4,19); + div_v:=div_v+to_unsigned(o_hsize*16,21); END IF; - dir_v(7):=NOT div_v(18); - IF div_v(18)='0' THEN - div_v:=div_v-to_unsigned(o_hsize*2,19); + dir_v(7):=NOT div_v(20); + + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*8,21); ELSE - div_v:=div_v+to_unsigned(o_hsize*2,19); + div_v:=div_v+to_unsigned(o_hsize*8,21); END IF; - dir_v(6):=NOT div_v(18); + dir_v(6):=NOT div_v(20); + END IF; + o_div(2)<=div_v; + o_dir(2)<=dir_v; + + div_v:=o_div(2); + dir_v:=o_dir(2); + IF FRAC>6 THEN + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*4,21); + ELSE + div_v:=div_v+to_unsigned(o_hsize*4,21); + END IF; + dir_v(5):=NOT div_v(20); + + IF div_v(20)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*2,21); + ELSE + div_v:=div_v+to_unsigned(o_hsize*2,21); + END IF; + dir_v(4):=NOT div_v(20); END IF; ----------------------------------- - o_hfrac<=dir_v; - o_hfrac1<=o_hfrac; o_hfrac2<=o_hfrac1; - o_hfrac3<=o_hfrac2; o_hfrac4<=o_hfrac3; + o_hfrac(1)<=dir_v; + o_hfrac(2 TO 9) <= o_hfrac(1 TO 8); - o_copyv(1 TO 8)<=o_copyv(0 TO 7); + o_copyv(1 TO 14)<=o_copyv(0 TO 13); o_dcptv(1)<=o_dcpt; IF o_dcptv(1)>=o_hsize THEN o_copyv(2)<='0'; END IF; o_dcptv(2)<=o_dcptv(1) MOD OHRES; - o_dcptv(3 TO 8)<=o_dcptv(2 TO 7); + o_dcptv(3 TO 14)<=o_dcptv(2 TO 13); - o_hpixq<=(o_hpix3,o_hpix2,o_hpix1,o_hpix0); - - -- NEAREST ------------------------------------------- -- C2 - o_h_near_frac<=near_frac(o_hfrac2); - - -- C3 - o_h_near_t<=near_calc(o_h_near_frac,o_hpixq); - - -- C4 : Nearest - o_h_near_pix.r<=o_h_near_t.r(7+FRAC DOWNTO FRAC); - o_h_near_pix.g<=o_h_near_t.g(7+FRAC DOWNTO FRAC); - o_h_near_pix.b<=o_h_near_t.b(7+FRAC DOWNTO FRAC); + o_hpixq(2)<=(o_hpix3,o_hpix2,o_hpix1,o_hpix0); + o_hpixq(3 TO 8)<=o_hpixq(2 TO 7); -- BILINEAR / SHARP BILINEAR --------------- - -- C1 : Pre-calc Sharp Bilinear - o_h_sbil_t<=sbil_frac1(o_hfrac1); + -- C7 : Pre-calc Sharp Bilinear + o_h_sbil_t<=sbil_frac1(o_hfrac(6)); - -- C2 : Select + -- C8 : Select o_h_bil_frac<=(OTHERS =>'0'); IF o_hmode(0)='1' THEN -- Bilinear IF MASK(MASK_BILINEAR)='1' THEN - o_h_bil_frac<=bil_frac(o_hfrac2); + o_h_bil_frac<=bil_frac(o_hfrac(7)); END IF; ELSE -- Sharp Bilinear IF MASK(MASK_SHARP_BILINEAR)='1' THEN - o_h_bil_frac<=sbil_frac2(o_hfrac2,o_h_sbil_t); + o_h_bil_frac<=sbil_frac2(o_hfrac(7),o_h_sbil_t); END IF; END IF; - -- C3 : Opposite frac - o_h_bil_t<=bil_calc(o_h_bil_frac,o_hpixq); + -- C9 : Opposite frac + o_h_bil_t<=bil_calc(o_h_bil_frac,o_hpixq(8)); - -- C4 : Bilinear / Sharp Bilinear + -- C10 : Bilinear / Sharp Bilinear o_h_bil_pix.r<=bound(o_h_bil_t.r,8+FRAC); o_h_bil_pix.g<=bound(o_h_bil_t.g,8+FRAC); o_h_bil_pix.b<=bound(o_h_bil_t.b,8+FRAC); -- BICUBIC ------------------------------------------- - -- C1 : Bicubic coefficients A,B,C,D + -- C8 : Bicubic coefficients A,B,C,D + -- C8 : Bicubic calc T1 = X.D + C + o_h_bic_abcd1<=bic_calc0(o_hfrac(7),o_hpixq(6)); + o_h_bic_tt1<=bic_calc1(o_hfrac(7), + bic_calc0(o_hfrac(7),o_hpixq(6))); - -- C2 : Bicubic calc T1 = X.D + C - o_h_bic_abcd1<=bic_calc0(o_hfrac2,(o_hpix3,o_hpix2,o_hpix1,o_hpix0)); - o_h_bic_tt1<=bic_calc1(o_hfrac2, - bic_calc0(o_hfrac2,(o_hpix3,o_hpix2,o_hpix1,o_hpix0))); - - -- C3 : Bicubic calc T2 = X.T1 + B + -- C9 : Bicubic calc T2 = X.T1 + B o_h_bic_abcd2<=o_h_bic_abcd1; - o_h_bic_tt2<=bic_calc2(o_hfrac3,o_h_bic_tt1,o_h_bic_abcd1); + o_h_bic_tt2<=bic_calc2(o_hfrac(8),o_h_bic_tt1,o_h_bic_abcd1); - -- C4 : Bicubic final Y = X.T2 + A - o_h_bic_pix<=bic_calc3(o_hfrac4,o_h_bic_tt2,o_h_bic_abcd2); + -- C10 : Bicubic final Y = X.T2 + A + o_h_bic_pix<=bic_calc3(o_hfrac(9),o_h_bic_tt2,o_h_bic_abcd2); -- POLYPHASE ----------------------------------------- - -- C1 : Read memory + -- C2 + IF o_hfrac(2)(o_hfrac(2)'left)='0' THEN + o_h_lum_pix<=o_hpix2; + ELSE + o_h_lum_pix<=o_hpix1; + END IF; + + -- C3-C8 in PolyFetch + + -- C9 : Apply Polyphase + o_h_poly_t<=poly_calc(o_h_poly_phase,o_hpixq(8)); + + -- C10 : Sum and bound + o_h_poly_pix<=poly_final(o_h_poly_t); - -- C2 : Filter calc - o_h_poly_dr2<=o_h_poly_dr; - - -- C3 : Add - o_h_poly_t<=poly_calc1(o_h_poly_dr2,o_hpixq); - - -- C4 : Bounding - o_h_poly_pix<=poly_calc2(o_h_poly_t); - - -- C5 : Select interpoler ---------------------------- - o_wadl<=o_dcptv(8); - o_wr<=o_altx AND (o_copyv(8) & o_copyv(8) & o_copyv(8) & o_copyv(8)); + -- C11 : Select interpoler ---------------------------- + o_wadl<=o_dcptv(14); + o_wr<=o_altx AND (o_copyv(14) & o_copyv(14) & o_copyv(14) & o_copyv(14)); o_ldw<=(x"00",x"00",x"00"); CASE o_hmode(2 DOWNTO 0) IS WHEN "000" => -- Nearest IF MASK(MASK_NEAREST)='1' THEN - o_ldw<=o_h_near_pix; + o_ldw<=o_h_poly_pix; END IF; WHEN "001" | "010" => -- Bilinear | Sharp Bilinear IF MASK(MASK_BILINEAR)='1' OR @@ -2421,10 +2621,10 @@ BEGIN IF o_wr(3)='1' THEN o_line3(o_wadl)<=o_ldw; END IF; -- READS - o_ldr0<=o_line0(o_radl); - o_ldr1<=o_line1(o_radl); - o_ldr2<=o_line2(o_radl); - o_ldr3<=o_line3(o_radl); + o_ldr0<=o_line0(o_radl0); + o_ldr1<=o_line1(o_radl1); + o_ldr2<=o_line2(o_radl2); + o_ldr3<=o_line3(o_radl3); END IF; END PROCESS OLBUF; @@ -2459,11 +2659,11 @@ BEGIN (o_vcpt=o_vsend AND o_hcpt=o_vmin AND o_vcpt_pre2<=o_vmax); - o_hsv(1 TO 5)<=o_hsv(0 TO 4); - o_vsv(1 TO 5)<=o_vsv(0 TO 4); - o_dev(1 TO 5)<=o_dev(0 TO 4); - o_pev(1 TO 5)<=o_pev(0 TO 4); - o_end(1 TO 5)<=o_end(0 TO 4); + o_hsv(1 TO 11)<=o_hsv(0 TO 10); + o_vsv(1 TO 11)<=o_vsv(0 TO 10); + o_dev(1 TO 11)<=o_dev(0 TO 10); + o_pev(1 TO 11)<=o_pev(0 TO 10); + o_end(1 TO 11)<=o_end(0 TO 10); IF o_run='0' THEN o_hsv(2)<='0'; @@ -2482,13 +2682,41 @@ BEGIN -- Vertical Scaler VSCAL:PROCESS(o_clk) IS VARIABLE pixq_v : arr_pix(0 TO 3); + VARIABLE vlumpix_v : type_pix; + VARIABLE r1_v, r2_v : natural RANGE 0 TO OHRES-1; + VARIABLE fracnn_v : std_logic; BEGIN IF rising_edge(o_clk) THEN IF o_ce='1' THEN + o_v_hmin_adj<=o_hmin + 5; + + fracnn_v := o_vfrac(o_vfrac'left); + r1_v := (o_hcpt - o_v_hmin_adj + OHRES) MOD OHRES; + r2_v := (o_hcpt - o_hmin + OHRES) MOD OHRES; + -- CYCLE 1 ----------------------------------------- -- Read mem - o_radl<=(o_hcpt - o_hmin + OHRES) MOD OHRES; - + o_radl0<=r1_v; + o_radl1<=r1_v; + o_radl2<=r1_v; + o_radl3<=r1_v; + + IF fracnn_v = '0' THEN + CASE o_vacptl IS + WHEN "10" => o_radl1<=r2_v; + WHEN "11" => o_radl2<=r2_v; + WHEN "00" => o_radl3<=r2_v; + WHEN OTHERS => o_radl0<=r2_v; + END CASE; + ELSE + CASE o_vacptl IS + WHEN "10" => o_radl2<=r2_v; + WHEN "11" => o_radl3<=r2_v; + WHEN "00" => o_radl0<=r2_v; + WHEN OTHERS => o_radl1<=r2_v; + END CASE; + END IF; + -- CYCLE 2 ----------------------------------------- -- Lines reordering CASE o_vacptl IS @@ -2497,37 +2725,47 @@ BEGIN WHEN "00" => pixq_v:=(o_ldr2,o_ldr3,o_ldr0,o_ldr1); WHEN OTHERS => pixq_v:=(o_ldr3,o_ldr0,o_ldr1,o_ldr2); END CASE; - - o_vpixq<=pixq_v; - - -- Bottom edge : replicate last line - IF to_integer(o_vacpt)=o_ivsize THEN - o_vpixq(2)<=pixq_v(2); + + IF fracnn_v = '0' THEN + o_vpix_outer<=(pixq_v(0), pixq_v(2), pixq_v(3)); + o_vpix_inner(0)<=pixq_v(1); + ELSE + o_vpix_outer<=(pixq_v(0), pixq_v(1), pixq_v(3)); + o_vpix_inner(0)<=pixq_v(2); END IF; - IF to_integer(o_vacpt)>=o_ivsize+1 THEN - o_vpixq(2)<=pixq_v(1); - o_vpixq(1)<=pixq_v(1); + + -- CYCLE 3-7 + o_vpix_inner(1 TO 5)<=o_vpix_inner(0 TO 4); + + -- CYCLE 8 + IF to_integer(o_vacpt)>o_ivsize THEN + IF fracnn_v = '0' THEN + o_vpixq_pre<=(o_vpix_outer(0), o_vpix_inner(5), o_vpix_inner(5), o_vpix_inner(5)); + ELSE + o_vpixq_pre<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_outer(1), o_vpix_outer(1)); + END IF; + ELSIF to_integer(o_vacpt)=o_ivsize THEN + IF fracnn_v = '0' THEN + o_vpixq_pre<=(o_vpix_outer(0), o_vpix_inner(5), o_vpix_outer(1), o_vpix_outer(1)); + ELSE + o_vpixq_pre<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_inner(5), o_vpix_inner(5)); + END IF; + ELSE + IF fracnn_v = '0' THEN + o_vpixq_pre<=(o_vpix_outer(0), o_vpix_inner(5), o_vpix_outer(1), o_vpix_outer(2)); + ELSE + o_vpixq_pre<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_inner(5), o_vpix_outer(2)); + END IF; END IF; - - o_vpixq1<=o_vpixq; - - -- NEAREST ----------------------------------------- - -- C4 - o_v_near_frac<=near_frac(o_vfrac); - - -- C5 - o_v_near_t<=near_calc(o_v_near_frac,o_vpixq1); - - -- C6 : Nearest - o_v_near_pix.r<=o_v_near_t.r(7+FRAC DOWNTO FRAC); - o_v_near_pix.g<=o_v_near_t.g(7+FRAC DOWNTO FRAC); - o_v_near_pix.b<=o_v_near_t.b(7+FRAC DOWNTO FRAC); + + -- CYCLE 9 + o_vpixq<=o_vpixq_pre; -- BILINEAR / SHARP BILINEAR ----------------------- - -- C3 : Pre-calc Sharp Bilinear + -- C8 : Pre-calc Sharp Bilinear o_v_sbil_t<=sbil_frac1(o_vfrac); - -- C4 : Select + -- C9 : Select o_v_bil_frac<=(OTHERS =>'0'); IF o_vmode(0)='1' THEN -- Bilinear IF MASK(MASK_BILINEAR)='1' THEN @@ -2538,56 +2776,56 @@ BEGIN o_v_bil_frac<=sbil_frac2(o_vfrac,o_v_sbil_t); END IF; END IF; + + -- C10 : + o_v_bil_t<=bil_calc(o_v_bil_frac,o_vpixq); - o_v_bil_t<=bil_calc(o_v_bil_frac,o_vpixq1); - - -- C6 : Bilinear / Sharp Bilinear + -- C11 : Nearest / Bilinear / Sharp Bilinear o_v_bil_pix.r<=bound(o_v_bil_t.r,8+FRAC); o_v_bil_pix.g<=bound(o_v_bil_t.g,8+FRAC); o_v_bil_pix.b<=bound(o_v_bil_t.b,8+FRAC); -- BICUBIC ----------------------------------------- - -- C3 : Bicubic coefficients A,B,C,D - - -- C4 : Bicubic calc T1 = X.D + C + -- C9 : Bicubic coefficients A,B,C,D + -- C9 : Bicubic calc T1 = X.D + C o_v_bic_abcd1<=bic_calc0(o_vfrac,o_vpixq); o_v_bic_tt1<=bic_calc1(o_vfrac,bic_calc0(o_vfrac,o_vpixq)); - -- C5 : Bicubic calc T2 = X.T1 + B + -- C10 : Bicubic calc T2 = X.T1 + B o_v_bic_abcd2<=o_v_bic_abcd1; o_v_bic_tt2<=bic_calc2(o_vfrac,o_v_bic_tt1,o_v_bic_abcd1); - -- C6 : Bicubic final Y = X.T2 + A + -- C11 : Bicubic final Y = X.T2 + A o_v_bic_pix<=bic_calc3(o_vfrac,o_v_bic_tt2,o_v_bic_abcd2); -- POLYPHASE --------------------------------------- - -- C3 : Read memory - - -- C4 : Filter calc - o_v_poly_dr2<=o_v_poly_dr; - - -- C5 : Add - o_v_poly_t<=poly_calc1(o_v_poly_dr2,o_vpixq1); - - -- C6 : Bounding - o_v_poly_pix<=poly_calc2(o_v_poly_t); - - -- CYCLE 6 ----------------------------------------- - o_hs<=o_hsv(5); - o_vs<=o_vsv(5); - o_de<=o_dev(5); - o_vbl<=o_end(5); + -- C3 : Setup luminance + o_v_lum_pix<=o_vpix_inner(0); + + -- C4-C9 in PolyFetch + + -- C10 : Apply polyphase + o_v_poly_t<=poly_calc(o_v_poly_phase,o_vpixq); + + -- C11 : Bound + o_v_poly_pix<=poly_final(o_v_poly_t); + + -- CYCLE 12 ----------------------------------------- + o_hs<=o_hsv(11); + o_vs<=o_vsv(11); + o_de<=o_dev(11); + o_vbl<=o_end(11); o_r<=x"00"; o_g<=x"00"; o_b<=x"00"; - o_brd<= not o_pev(5); + o_brd<= not o_pev(11); CASE o_vmode(2 DOWNTO 0) IS WHEN "000" => -- Nearest IF MASK(MASK_NEAREST)='1' THEN - o_r<=o_v_near_pix.r; - o_g<=o_v_near_pix.g; - o_b<=o_v_near_pix.b; + o_r<=o_v_poly_pix.r; + o_g<=o_v_poly_pix.g; + o_b<=o_v_poly_pix.b; END IF; WHEN "001" | "010" => -- Bilinear | Sharp Bilinear IF MASK(MASK_BILINEAR)='1' OR @@ -2611,7 +2849,7 @@ BEGIN END IF; END CASE; - IF o_pev(5)='0' THEN + IF o_pev(11)='0' THEN o_r<=o_border(23 DOWNTO 16); -- Copy border colour o_g<=o_border(15 DOWNTO 8); o_b<=o_border(7 DOWNTO 0); diff --git a/sys/scanlines.v b/sys/scanlines.v index 59d29bd..43f890f 100644 --- a/sys/scanlines.v +++ b/sys/scanlines.v @@ -5,11 +5,11 @@ module scanlines #(parameter v2=0) input [1:0] scanlines, input [23:0] din, input hs_in,vs_in, - input de_in, + input de_in,ce_in, output reg [23:0] dout, output reg hs_out,vs_out, - output reg de_out + output reg de_out,ce_out ); reg [1:0] scanline; @@ -56,12 +56,13 @@ end always @(posedge clk) begin reg [23:0] dout1, dout2; - reg de1,de2,vs1,vs2,hs1,hs2; + reg de1,de2,vs1,vs2,hs1,hs2,ce1,ce2; dout <= dout2; dout2 <= dout1; dout1 <= d; vs_out <= vs2; vs2 <= vs1; vs1 <= vs_in; hs_out <= hs2; hs2 <= hs1; hs1 <= hs_in; de_out <= de2; de2 <= de1; de1 <= de_in; + ce_out <= ce2; ce2 <= ce1; ce1 <= ce_in; end endmodule diff --git a/sys/sys_top.v b/sys/sys_top.v index 5275d0b..635ae56 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -295,8 +295,8 @@ reg [31:0] cfg_custom_p2; reg [4:0] vol_att; initial vol_att = 5'b11111; -reg [8:0] coef_addr; -reg [8:0] coef_data; +reg [11:0] coef_addr; +reg [9:0] coef_data; reg coef_wr = 0; wire[12:0] ARX, ARY; @@ -377,14 +377,14 @@ always@(posedge clk_sys) begin cfg_set <= 0; if(cnt<8) begin case(cnt[2:0]) - 0: if(WIDTH != io_din[11:0]) WIDTH <= io_din[11:0]; - 1: if(HFP != io_din[11:0]) HFP <= io_din[11:0]; - 2: if(HS != io_din[11:0]) HS <= io_din[11:0]; - 3: if(HBP != io_din[11:0]) HBP <= io_din[11:0]; - 4: if(HEIGHT != io_din[11:0]) HEIGHT <= io_din[11:0]; - 5: if(VFP != io_din[11:0]) VFP <= io_din[11:0]; - 6: if(VS != io_din[11:0]) VS <= io_din[11:0]; - 7: if(VBP != io_din[11:0]) VBP <= io_din[11:0]; + 0: WIDTH <= io_din[11:0]; + 1: HFP <= io_din[11:0]; + 2: HS <= {io_din[15], io_din[11:0]}; + 3: HBP <= io_din[11:0]; + 4: HEIGHT <= io_din[11:0]; + 5: VFP <= io_din[11:0]; + 6: VS <= {io_din[15],io_din[11:0]}; + 7: VBP <= io_din[11:0]; endcase `ifndef MISTER_DEBUG_NOHDMI if(cnt == 1) begin @@ -423,8 +423,8 @@ always@(posedge clk_sys) begin if(cmd == 'h26) vol_att <= io_din[4:0]; if(cmd == 'h27) VSET <= io_din[11:0]; if(cmd == 'h2A) begin - if(cnt[0]) {coef_wr,coef_data} <= {1'b1,io_din[8:0]}; - else coef_addr <= io_din[8:0]; + if(cnt[0]) {coef_wr,coef_data} <= {1'b1,io_din[9:0]}; + else coef_addr <= io_din[11:0]; end if(cmd == 'h2B) scaler_flt <= io_din[2:0]; if(cmd == 'h37) {FREESCALE,HSET} <= {io_din[15],io_din[11:0]}; @@ -641,7 +641,13 @@ ascal .PALETTE2("false"), `endif `endif - .FRAC(6), +`ifdef MISTER_DISABLE_ADAPTIVE + .ADAPTIVE("false"), +`endif +`ifdef MISTER_DOWNSCALE_NN + .DOWNSCALE_NN("true"), +`endif + .FRAC(8), .N_DW(128), .N_AW(28) ) @@ -677,15 +683,15 @@ ascal .o_vbl (hdmi_vbl), .o_brd (hdmi_brd), .o_lltune (lltune), - .htotal (WIDTH + HFP + HBP + HS), + .htotal (WIDTH + HFP + HBP + HS[11:0]), .hsstart (WIDTH + HFP), - .hsend (WIDTH + HFP + HS), + .hsend (WIDTH + HFP + HS[11:0]), .hdisp (WIDTH), .hmin (hmin), .hmax (hmax), - .vtotal (HEIGHT + VFP + VBP + VS), + .vtotal (HEIGHT + VFP + VBP + VS[11:0]), .vsstart (HEIGHT + VFP), - .vsend (HEIGHT + VFP + VS), + .vsend (HEIGHT + VFP + VS[11:0]), .vdisp (HEIGHT), .vmin (vmin), .vmax (vmax), @@ -951,11 +957,11 @@ pll_hdmi pll_hdmi //1920x1080@60 PCLK=148.5MHz CEA reg [11:0] WIDTH = 1920; reg [11:0] HFP = 88; -reg [11:0] HS = 48; +reg [12:0] HS = 48; reg [11:0] HBP = 148; reg [11:0] HEIGHT = 1080; reg [11:0] VFP = 4; -reg [11:0] VS = 5; +reg [12:0] VS = 5; reg [11:0] VBP = 36; wire [63:0] reconfig_to_pll; @@ -1208,13 +1214,21 @@ reg hdmi_out_de; reg [23:0] hdmi_out_d; always @(posedge hdmi_tx_clk) begin + reg [23:0] hdmi_dv_data; + reg hdmi_dv_hs, hdmi_dv_vs, hdmi_dv_de; + reg hs,vs,de; reg [23:0] d; - hs <= (~vga_fb & direct_video) ? dv_hs : (direct_video & csync_en) ? hdmi_cs_osd : hdmi_hs_osd; - vs <= (~vga_fb & direct_video) ? dv_vs : hdmi_vs_osd; - de <= (~vga_fb & direct_video) ? dv_de : hdmi_de_osd; - d <= (~vga_fb & direct_video) ? dv_data : hdmi_data_osd; + hdmi_dv_data <= dv_data; + hdmi_dv_hs <= dv_hs; + hdmi_dv_vs <= dv_vs; + hdmi_dv_de <= dv_de; + + hs <= (~vga_fb & direct_video) ? hdmi_dv_hs : (direct_video & csync_en) ? hdmi_cs_osd : hdmi_hs_osd; + vs <= (~vga_fb & direct_video) ? hdmi_dv_vs : hdmi_vs_osd; + de <= (~vga_fb & direct_video) ? hdmi_dv_de : hdmi_de_osd; + d <= (~vga_fb & direct_video) ? hdmi_dv_data : hdmi_data_osd; hdmi_out_hs <= hs; hdmi_out_vs <= vs; @@ -1230,7 +1244,7 @@ assign HDMI_TX_D = hdmi_out_d; ///////////////////////// VGA output ////////////////////////////////// wire [23:0] vga_data_sl; -wire vga_de_sl, vga_vs_sl, vga_hs_sl; +wire vga_de_sl, vga_ce_sl, vga_vs_sl, vga_hs_sl; scanlines #(0) VGA_scanlines ( .clk(clk_vid), @@ -1240,11 +1254,13 @@ scanlines #(0) VGA_scanlines .hs_in(hs_fix), .vs_in(vs_fix), .de_in(de_emu), + .ce_in(ce_pix), .dout(vga_data_sl), .hs_out(vga_hs_sl), .vs_out(vga_vs_sl), - .de_out(vga_de_sl) + .de_out(vga_de_sl), + .ce_out(vga_ce_sl) ); wire [23:0] vga_data_osd; @@ -1307,11 +1323,11 @@ csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd); wire cs1 = (vga_fb | vga_scaler) ? vgas_cs : vga_cs; - assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : ((vga_fb | vga_scaler) ? ~vgas_vs : ~vga_vs) | csync_en; - assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : (vga_fb | vga_scaler) ? (csync_en ? ~vgas_cs : ~vgas_hs) : (csync_en ? ~vga_cs : ~vga_hs); - assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : vga_o[23:18]; - assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : vga_o[15:10]; - assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : vga_o[7:2] ; + assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ :((((vga_fb | vga_scaler) ? ~vgas_vs : ~vga_vs) | csync_en) ^ VS[12]); + assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : (((vga_fb | vga_scaler) ? (csync_en ? ~vgas_cs : ~vgas_hs) : (csync_en ? ~vga_cs : ~vga_hs)) ^ HS[12]); + assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : vga_o[23:18]; + assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : vga_o[15:10]; + assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : vga_o[7:2] ; `endif reg video_sync = 0; @@ -1479,7 +1495,7 @@ sync_fix sync_h(clk_vid, hs_emu, hs_fix); wire [6:0] user_out, user_in; assign clk_ihdmi= clk_vid; -assign ce_hpix = ce_pix; +assign ce_hpix = vga_ce_sl; assign hr_out = vga_data_sl[23:16]; assign hg_out = vga_data_sl[15:8]; assign hb_out = vga_data_sl[7:0]; @@ -1522,11 +1538,15 @@ wire [13:0] fb_stride; assign fb_stride = 0; `endif +reg [1:0] sl_r; +wire [1:0] sl = sl_r; +always @(posedge clk_sys) sl_r <= FB_EN ? 2'b00 : scanlines; + emu emu ( .CLK_50M(FPGA_CLK2_50), .RESET(reset), - .HPS_BUS({scanlines,f1, HDMI_TX_VS, + .HPS_BUS({fb_en, sl, f1, HDMI_TX_VS, clk_100m, clk_ihdmi, ce_hpix, hde_emu, hhs_fix, hvs_fix, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),