From 577dbea6a1d73a9a4bb3d0e2e8f4e8bf0c53a339 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Thu, 27 Dec 2018 18:21:19 +0800 Subject: [PATCH] Update sys. New scaler. --- zxspectrum.qpf => ZX-Spectrum-vip.qpf | 3 +- zxspectrum.qsf => ZX-Spectrum-vip.qsf | 0 zxspectrum.srf => ZX-Spectrum-vip.srf | 0 ZX-Spectrum.qpf | 12 + zxspectrum-lite.qsf => ZX-Spectrum.qsf | 17 +- zxspectrum.sdc => ZX-Spectrum.sdc | 0 zxspectrum-lite.srf => ZX-Spectrum.srf | 0 zxspectrum.sv => ZX-Spectrum.sv | 69 +- zxspectrum_Q13.qpf => ZX-Spectrum_Q13.qpf | 2 +- zxspectrum_Q13.qsf => ZX-Spectrum_Q13.qsf | 4 +- zxspectrum_Q13.srf => ZX-Spectrum_Q13.srf | 2 + sys/ascal.vhd | 2505 +++++++++++++++++++++ sys/coeff.mif | 71 + sys/hdmi_config.sv | 4 +- sys/hdmi_lite.sv | 395 ---- sys/hps_io.v | 1 + sys/lpf48k.sv | 4 +- sys/osd.v | 125 +- sys/pattern_vg.v | 120 - sys/pll.qip | 16 +- sys/pll.v | 10 +- sys/pll/pll_0002.v | 9 +- sys/reset_source.v | 50 + sys/scanlines.v | 52 + sys/sync_vg.v | 78 - sys/sys.qip | 50 +- sys/sys_q13.qip | 58 +- sys/sys_top.v | 351 +-- sys/sysmem.sv | 149 +- sys/vip.qsys | 231 +- sys/vip_config.sv | 169 +- 31 files changed, 3476 insertions(+), 1081 deletions(-) rename zxspectrum.qpf => ZX-Spectrum-vip.qpf (73%) rename zxspectrum.qsf => ZX-Spectrum-vip.qsf (100%) rename zxspectrum.srf => ZX-Spectrum-vip.srf (100%) create mode 100644 ZX-Spectrum.qpf rename zxspectrum-lite.qsf => ZX-Spectrum.qsf (93%) rename zxspectrum.sdc => ZX-Spectrum.sdc (100%) rename zxspectrum-lite.srf => ZX-Spectrum.srf (100%) rename zxspectrum.sv => ZX-Spectrum.sv (95%) rename zxspectrum_Q13.qpf => ZX-Spectrum_Q13.qpf (82%) rename zxspectrum_Q13.qsf => ZX-Spectrum_Q13.qsf (97%) rename zxspectrum_Q13.srf => ZX-Spectrum_Q13.srf (89%) create mode 100644 sys/ascal.vhd create mode 100644 sys/coeff.mif delete mode 100644 sys/hdmi_lite.sv delete mode 100644 sys/pattern_vg.v create mode 100644 sys/reset_source.v create mode 100644 sys/scanlines.v delete mode 100644 sys/sync_vg.v diff --git a/zxspectrum.qpf b/ZX-Spectrum-vip.qpf similarity index 73% rename from zxspectrum.qpf rename to ZX-Spectrum-vip.qpf index baca607..458ce5d 100644 --- a/zxspectrum.qpf +++ b/ZX-Spectrum-vip.qpf @@ -9,5 +9,4 @@ DATE = "23:13:02 April 27, 2017" # Revisions -PROJECT_REVISION = "zxspectrum" -PROJECT_REVISION = "zxspectrum-lite" +PROJECT_REVISION = "ZX-Spectrum-vip" diff --git a/zxspectrum.qsf b/ZX-Spectrum-vip.qsf similarity index 100% rename from zxspectrum.qsf rename to ZX-Spectrum-vip.qsf diff --git a/zxspectrum.srf b/ZX-Spectrum-vip.srf similarity index 100% rename from zxspectrum.srf rename to ZX-Spectrum-vip.srf diff --git a/ZX-Spectrum.qpf b/ZX-Spectrum.qpf new file mode 100644 index 0000000..7655cdd --- /dev/null +++ b/ZX-Spectrum.qpf @@ -0,0 +1,12 @@ +# +# please keep this file read-only! +# Quartus changes this file everytime revision is switched, +# and it will be marked as changed with every commit. +# + +QUARTUS_VERSION = "16.1" +DATE = "23:13:02 April 27, 2017" + +# Revisions + +PROJECT_REVISION = "ZX-Spectrum" diff --git a/zxspectrum-lite.qsf b/ZX-Spectrum.qsf similarity index 93% rename from zxspectrum-lite.qsf rename to ZX-Spectrum.qsf index 14eaa25..dd8627d 100644 --- a/zxspectrum-lite.qsf +++ b/ZX-Spectrum.qsf @@ -30,7 +30,7 @@ set_global_assignment -name FAMILY "Cyclone V" set_global_assignment -name DEVICE 5CSEBA6U23I7 set_global_assignment -name TOP_LEVEL_ENTITY sys_top set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.1.2 -set_global_assignment -name LAST_QUARTUS_VERSION "17.0.1 Standard Edition" +set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition" set_global_assignment -name PROJECT_CREATION_TIME_DATE "01:53:30 APRIL 20, 2017" set_global_assignment -name DEVICE_FILTER_PACKAGE UFBGA set_global_assignment -name DEVICE_FILTER_PIN_COUNT 672 @@ -358,7 +358,7 @@ set_global_assignment -name CDF_FILE jtag.cdf set_global_assignment -name QIP_FILE sys/sys.qip set_global_assignment -name QIP_FILE t80/T80.qip set_global_assignment -name QIP_FILE jt12/jt12.qip -set_global_assignment -name SDC_FILE zxspectrum.sdc +set_global_assignment -name SDC_FILE ZX-Spectrum.sdc set_global_assignment -name SYSTEMVERILOG_FILE saa1099.sv set_global_assignment -name SYSTEMVERILOG_FILE turbosound.sv set_global_assignment -name SYSTEMVERILOG_FILE ym2149.sv @@ -375,5 +375,16 @@ set_global_assignment -name VERILOG_FILE dpram.v set_global_assignment -name SYSTEMVERILOG_FILE tape.sv set_global_assignment -name VERILOG_FILE mouse.v set_global_assignment -name SYSTEMVERILOG_FILE keyboard.sv -set_global_assignment -name SYSTEMVERILOG_FILE zxspectrum.sv +set_global_assignment -name SYSTEMVERILOG_FILE ZX-Spectrum.sv +set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON +set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON +set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON +set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON +set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON +set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/zxspectrum.sdc b/ZX-Spectrum.sdc similarity index 100% rename from zxspectrum.sdc rename to ZX-Spectrum.sdc diff --git a/zxspectrum-lite.srf b/ZX-Spectrum.srf similarity index 100% rename from zxspectrum-lite.srf rename to ZX-Spectrum.srf diff --git a/zxspectrum.sv b/ZX-Spectrum.sv similarity index 95% rename from zxspectrum.sv rename to ZX-Spectrum.sv index e9dffae..b077546 100644 --- a/zxspectrum.sv +++ b/ZX-Spectrum.sv @@ -47,6 +47,8 @@ module emu output VGA_HS, output VGA_VS, output VGA_DE, // = ~(VBlank | HBlank) + output VGA_F1, + output [1:0] VGA_SL, output LED_USER, // 1 - ON, 0 - OFF. @@ -93,9 +95,18 @@ module emu output SDRAM_nCS, output SDRAM_nCAS, output SDRAM_nRAS, - output SDRAM_nWE + output SDRAM_nWE, + + input UART_CTS, + output UART_RTS, + input UART_RXD, + output UART_TXD, + output UART_DTR, + input UART_DSR ); +assign VGA_F1 = 0; +assign {UART_RTS, UART_TXD, UART_DTR} = 0; assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; assign AUDIO_S = 1; @@ -146,16 +157,14 @@ localparam CONF_STR1 = { localparam CONF_STR2 = { "0,Reset & apply;", "J,Fire 1,Fire 2;", - "V,v3.91.",`BUILD_DATE + "V,v",`BUILD_DATE }; //////////////////// CLOCKS /////////////////// -assign CLK_VIDEO = clk_sys; - wire locked; -wire clk_sys; +wire clk_sys, clk_vid; pll pll ( @@ -163,6 +172,7 @@ pll pll .rst(0), .outclk_0(clk_sys), .outclk_1(SDRAM_CLK), + .outclk_2(clk_vid), .locked(locked) ); @@ -753,7 +763,54 @@ always_comb begin endcase end -video video(.*, .ce_pix(CE_PIXEL), .din(cpu_dout), .page_ram(page_ram[2:0]), .scale(status[16:15]), .wide(status[5])); +wire [1:0] scale = status[16:15]; +assign VGA_SL = {scale == 3, scale == 2}; + +video video +( + .*, + .ce_pix(ce_vid1), + + .VGA_R(r2), + .VGA_G(g2), + .VGA_B(b2), + .VGA_HS(hs2), + .VGA_VS(vs2), + .VGA_DE(de2), + + .din(cpu_dout), + .page_ram(page_ram[2:0]), + .scale(scale == 1), + .forced_scandoubler(forced_scandoubler || scale), + .wide(status[5]) +); + +wire ce_vid1; +reg ce_vid2; +always @(posedge clk_sys) ce_vid2 <= ce_vid1; + +wire ce_vid = ce_vid2 | ce_vid1; + +reg ce_pix, ce_pix1; +reg [7:0] r,r1,r2,g,g1,g2,b,b1,b2; +reg hs,hs1,hs2,vs,vs1,vs2,de,de1,de2; + +always @(posedge clk_vid) begin + ce_pix1 <= ce_vid; + ce_pix <= ce_pix1; + + {r1,g1,b1} <= {r2,g2,b2}; + {r,g,b} <= {r1,g1,b1}; + + {hs1,vs1,de1} <= {hs2,vs2,de2}; + {hs,vs,de} <= {hs1,vs1,de1}; +end + +assign {VGA_R,VGA_G,VGA_B} = {r,g,b}; +assign {VGA_HS,VGA_VS,VGA_DE} = {hs,vs,de}; +assign CE_PIXEL = ce_pix; +assign CLK_VIDEO = clk_vid; + reg new_vmode = 0; always @(posedge clk_sys) begin diff --git a/zxspectrum_Q13.qpf b/ZX-Spectrum_Q13.qpf similarity index 82% rename from zxspectrum_Q13.qpf rename to ZX-Spectrum_Q13.qpf index e2ee615..7ced2d0 100644 --- a/zxspectrum_Q13.qpf +++ b/ZX-Spectrum_Q13.qpf @@ -9,4 +9,4 @@ DATE = "23:13:02 April 27, 2017" # Revisions -PROJECT_REVISION = "zxspectrum_Q13" +PROJECT_REVISION = "ZX-Spectrum_Q13" diff --git a/zxspectrum_Q13.qsf b/ZX-Spectrum_Q13.qsf similarity index 97% rename from zxspectrum_Q13.qsf rename to ZX-Spectrum_Q13.qsf index 86e3aa8..19c680b 100644 --- a/zxspectrum_Q13.qsf +++ b/ZX-Spectrum_Q13.qsf @@ -361,7 +361,7 @@ set_global_assignment -name CDF_FILE jtag.cdf set_global_assignment -name QIP_FILE sys/sys_q13.qip set_global_assignment -name QIP_FILE t80/T80.qip set_global_assignment -name QIP_FILE jt12/jt12.qip -set_global_assignment -name SDC_FILE zxspectrum.sdc +set_global_assignment -name SDC_FILE ZX-Spectrum.sdc set_global_assignment -name SYSTEMVERILOG_FILE saa1099.sv set_global_assignment -name SYSTEMVERILOG_FILE turbosound.sv set_global_assignment -name SYSTEMVERILOG_FILE ym2149.sv @@ -378,5 +378,5 @@ set_global_assignment -name VERILOG_FILE dpram.v set_global_assignment -name SYSTEMVERILOG_FILE tape.sv set_global_assignment -name VERILOG_FILE mouse.v set_global_assignment -name SYSTEMVERILOG_FILE keyboard.sv -set_global_assignment -name SYSTEMVERILOG_FILE zxspectrum.sv +set_global_assignment -name SYSTEMVERILOG_FILE ZX-Spectrum.sv set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/zxspectrum_Q13.srf b/ZX-Spectrum_Q13.srf similarity index 89% rename from zxspectrum_Q13.srf rename to ZX-Spectrum_Q13.srf index 38461e4..977fafe 100644 --- a/zxspectrum_Q13.srf +++ b/ZX-Spectrum_Q13.srf @@ -19,7 +19,9 @@ { "" "" "" "Design contains 4 input pin(s) that do not drive logic" { } { } 0 21074 "" 0 0 "Quartus II" 0 -1 0 ""} { "" "" "" "24 hierarchies have connectivity warnings - see the Connectivity Checks report folder" { } { } 0 12241 "" 0 0 "Quartus II" 0 -1 0 ""} { "" "" "" "Following 5 pins have no output enable or a GND or VCC output enable - later changes to this connectivity may change fitting results" { } { } 0 169064 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[2\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Quartus II" 0 -1 0 ""} { "" "" "" "*" { } { } 0 10268 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 276027 "" 0 0 "Quartus II" 0 -1 0 ""} { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Quartus II" 0 -1 0 ""} { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Quartus II" 0 -1 0 ""} { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Quartus II" 0 -1 0 ""} diff --git a/sys/ascal.vhd b/sys/ascal.vhd new file mode 100644 index 0000000..516526c --- /dev/null +++ b/sys/ascal.vhd @@ -0,0 +1,2505 @@ +-------------------------------------------------------------------------------- +-- AVALON SCALER +-------------------------------------------------------------------------------- +-- TEMLIB 10/2018 +-------------------------------------------------------------------------------- +-- This code can be freely distributed and used for any purpose, but, if you +-- find any bug, or want to suggest an enhancement, you ought to send a mail +-- to info@temlib.org. +-------------------------------------------------------------------------------- + +-- Features : +-- - Arbitrary output video format +-- - Autodetect input image size or fixed window +-- - Progressive and interlaced input +-- - Interpolation +-- Upscaling : Nearest, Bilinear, Sharp Bilinear, Bicubic, Polyphase +-- Downscaling : Nearest, Bilinear +-- - Avalon bus interface with 128 or 64 bits DATA +-- - Optional triple buffering +-- - Support for external low lag syntonization + +-------------------------------------------- +-- Downscaling +-- - Horizontal and vertical up-/down-scaling are independant. +-- - Downscaling, H and/or V, supports only nearest-neighbour and bilinear +-- filtering. +-- - For interlaced video, when the vertical size is lower than a deinterlaced +-- frame size (2x half-frame), the scaler processes only half-frames +-- and upscales (when the output size is between 1x an 2x) or downscales (size +-- below 1x) them. + +-------------------------------------------- +-- 4 asynchronous clock domains : +-- i_xxx : Input video +-- o_xxx : Output video +-- avl_xxx : Avalon memory bus +-- poly_xxx : Polyphase filters memory + +-------------------------------------------- +-- Mode 24bits + +-------------------------------------------- +-- Image header. When HEADER = TRUE +-- Header Address = RAMBASE +-- Image Address = RAMBASE + HEADER_SIZE + +-- Header (Bytes. Big Endian.) +-- 0 : Type = 1 +-- 1 : Pixel format +-- 1 : 24 bits/pixel, packed RGB. Big Endian + +-- 3:2 : Header size : Offset to start of picture (= N_BURST) +-- 5:4 : Attributes. TBD +-- b0 ; Interlaced +-- b1 : Field number +-- b2 : Horizontal downscaled +-- b3 : Vertical downscaled +-- 7:6 : Image width. Pixels. +-- 9:8 : Image height. Pixels. +-- 11:10 : Line length. Bytes. +-- 13:12 : TBD. +-- 15:14 : TBD. +-------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +-- MODE[2:0] +-- 000 : Nearest +-- 001 : Bilinear +-- 010 : Sharp Bilinear +-- 011 : Bicubic +-- 100 : Polyphase +-- 101 : TBD +-- 110 : TBD +-- 111 : TEST + +-- MODE[3] +-- 0 : Direct. Single framebuffer. +-- 1 : Triple buffering + +-- MODE[4] : TBD + +-- MASK : Enable / Disable selected interpoler +-- 0:Nearest 1:Bilinear 2:SharpBilinear 3:Bicubic 4:Polyphase +-- RAMBASE : RAM base address for framebuffer +-- RAMSIZE : RAM allocated for one framebuffer (needs x3 if triple-buffering) +-- Must be a power of two +-- INTER : True=Autodetect interlaced video False=Force progressive scan +-- HEADER : True=Add image properties header +-- SYNCHRO : True=Support synchronized mode False=Force disabled +-- DOWNSCALE : True=Support downscaling False=Downscaling disabled +-- FRAC : Fractional bits, subpixel resolution +-- FORMAT : TBD +-- OHRES : Max. output horizontal resolution. Must be a power of two. +-- (Used for sizing line buffers) +-- IHRES : Max. input horizontal resolution. Must be a power of two. +-- (Used for sizing line buffers) +-- N_DW : Avalon data bus width. 64 or 128 bits +-- N_AW : Avalon address bus width +-- N_BURST : Burst size in bytes. Power of two. + +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; + SYNCHRO : boolean := true; + DOWNSCALE : boolean := true; + FRAC : natural RANGE 4 TO 6 :=4; + FORMAT : natural RANGE 1 TO 8 :=1; + 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 ( + ------------------------------------ + -- Input video + i_r : IN unsigned(7 DOWNTO 0); + i_g : IN unsigned(7 DOWNTO 0); + i_b : IN unsigned(7 DOWNTO 0); + i_hs : IN std_logic; -- H sync + i_vs : IN std_logic; -- V sync + i_fl : IN std_logic; -- Interlaced field + i_de : IN std_logic; -- Display Enable + i_ce : IN std_logic; -- Clock Enable + i_clk : IN std_logic; -- Input clock + + ------------------------------------ + -- Output video + o_r : OUT unsigned(7 DOWNTO 0); + o_g : OUT unsigned(7 DOWNTO 0); + o_b : OUT unsigned(7 DOWNTO 0); + o_hs : OUT std_logic; -- H sync + o_vs : OUT std_logic; -- V sync + o_de : OUT std_logic; -- Display Enable + o_ce : IN std_logic; -- Clock Enable + o_clk : IN std_logic; -- Output clock + + ------------------------------------ + -- Low lag PLL tuning + o_lltune : OUT unsigned(15 DOWNTO 0); + + ------------------------------------ + -- Input video parameters + iauto : IN std_logic; -- 1=Autodetect image size 0=Choose window + himin : IN natural RANGE 0 TO 4095; -- MIN < MAX, MIN >=0, MAX < DISP + himax : IN natural RANGE 0 TO 4095; + vimin : IN natural RANGE 0 TO 4095; + vimax : IN natural RANGE 0 TO 4095; + + -- Output video parameters + run : IN std_logic; -- 1=Enable output image. 0=No image + freeze : IN std_logic; -- 1=Disable framebuffer writes + mode : IN unsigned(4 DOWNTO 0); + -- SYNC |________________________/"""""""""\______| + -- DE |""""""""""""""""""\______________________| + -- RGB | <#IMAGE#> ^HDISP | + -- ^HMIN ^HMAX ^HSSTART ^HSEND ^HTOTAL + htotal : IN natural RANGE 0 TO 4095; + hsstart : IN natural RANGE 0 TO 4095; + hsend : IN natural RANGE 0 TO 4095; + hdisp : IN natural RANGE 0 TO 4095; + hmin : IN natural RANGE 0 TO 4095; + hmax : IN natural RANGE 0 TO 4095; -- 0 <= hmin < hmax < hdisp + vtotal : IN natural RANGE 0 TO 4095; + vsstart : IN natural RANGE 0 TO 4095; + vsend : IN natural RANGE 0 TO 4095; + vdisp : IN natural RANGE 0 TO 4095; + vmin : IN natural RANGE 0 TO 4095; + vmax : IN natural RANGE 0 TO 4095; -- 0 <= vmin < vmax < vdisp + + ------------------------------------ + -- Polyphase filter coefficients + -- Order : + -- [Horizontal] [Vertical] + -- [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_wr : IN std_logic; + + ------------------------------------ + -- Avalon + avl_clk : IN std_logic; -- Avalon clock + avl_waitrequest : IN std_logic; + avl_readdata : IN std_logic_vector(N_DW-1 DOWNTO 0); + avl_readdatavalid : IN std_logic; + avl_burstcount : OUT std_logic_vector(7 DOWNTO 0); + avl_writedata : OUT std_logic_vector(N_DW-1 DOWNTO 0); + avl_address : OUT std_logic_vector(N_AW-1 DOWNTO 0); + avl_write : OUT std_logic; + avl_read : OUT std_logic; + avl_byteenable : OUT std_logic_vector(N_DW/8-1 DOWNTO 0); + + ------------------------------------ + reset_na : IN std_logic + ); + +BEGIN + ASSERT N_DW=64 OR N_DW=128 REPORT "DW" SEVERITY failure; + +END ENTITY ascal; + +--############################################################################## + +ARCHITECTURE rtl OF ascal IS + + CONSTANT MASK_NEAREST : natural :=0; + CONSTANT MASK_BILINEAR : natural :=1; + CONSTANT MASK_SHARP_BILINEAR : natural :=2; + CONSTANT MASK_BICUBIC : natural :=3; + CONSTANT MASK_POLY : natural :=4; + + ---------------------------------------------------------- + FUNCTION ilog2 (CONSTANT v : natural) RETURN natural IS + VARIABLE r : natural := 1; + VARIABLE n : natural := 0; + BEGIN + WHILE v>r LOOP + n:=n+1; + r:=r*2; + END LOOP; + RETURN n; + END FUNCTION ilog2; + FUNCTION to_std_logic (a : boolean) RETURN std_logic IS + BEGIN + IF a THEN RETURN '1'; + ELSE RETURN '0'; + END IF; + END FUNCTION to_std_logic; + + ---------------------------------------------------------- + CONSTANT NB_BURST : natural :=ilog2(N_BURST); + CONSTANT NB_LA : natural :=ilog2(N_DW/8); -- Low address bits + CONSTANT BLEN : natural :=N_BURST / N_DW * 8; -- Burst length + CONSTANT NP : natural :=24; + + ---------------------------------------------------------- + TYPE arr_dw IS ARRAY (natural RANGE <>) OF unsigned(N_DW-1 DOWNTO 0); + + TYPE type_pix IS RECORD + r,g,b : unsigned(7 DOWNTO 0); -- 0.8 + END RECORD; + TYPE arr_pix IS ARRAY (natural RANGE <>) OF type_pix; + ATTRIBUTE ramstyle : string; + + SUBTYPE uint12 IS natural RANGE 0 TO 4095; + + ---------------------------------------------------------- + -- Input image + SIGNAL i_freeze : std_logic; + SIGNAL i_hsize,i_hmin,i_hmax,i_hcpt : uint12; + SIGNAL i_hrsize,i_vrsize : uint12; + SIGNAL i_himax,i_vimax : uint12; + SIGNAL i_vsize,i_vmaxmin,i_vmin,i_vmax,i_vimaxc,i_vcpt : uint12; + SIGNAL i_iauto : std_logic; + SIGNAL i_mode : unsigned(4 DOWNTO 0); + SIGNAL i_ven,i_sof : std_logic; + SIGNAL i_wr : std_logic; + SIGNAL i_divstart,i_divrun : std_logic; + SIGNAL i_de_pre,i_hs_pre,i_vs_pre,i_fl_pre : std_logic; + SIGNAL i_hs_delay : natural RANGE 0 TO 15; + SIGNAL i_intercnt : natural RANGE 0 TO 3; + SIGNAL i_inter,i_half,i_flm : std_logic; + SIGNAL i_write,i_write_pre,i_walt : std_logic; + SIGNAL i_push,i_pushend,i_pushend2,i_eol,i_eol2,i_eol3,i_eol4 : std_logic; + SIGNAL i_pushhead,i_hbfix : std_logic; + SIGNAL i_hburst,i_hbcpt : natural RANGE 0 TO 31; + SIGNAL i_shift : unsigned(0 TO 119) := (OTHERS =>'0'); + SIGNAL i_head : unsigned(127 DOWNTO 0); + SIGNAL i_acpt : natural RANGE 0 TO 15; + SIGNAL i_dpram : arr_dw(0 TO BLEN*2-1); + ATTRIBUTE ramstyle OF i_dpram : SIGNAL IS "no_rw_check"; + SIGNAL i_endframe,i_syncline : std_logic; + SIGNAL i_wad : natural RANGE 0 TO BLEN*2-1; + SIGNAL i_dw : unsigned(N_DW-1 DOWNTO 0); + SIGNAL i_adrs,i_adrsi : unsigned(31 DOWNTO 0); -- Avalon address + SIGNAL i_reset_na : std_logic; + SIGNAL i_hnp,i_vnp : std_logic; + SIGNAL i_line : arr_pix(0 TO IHRES-1); -- Downscale line buffer + ATTRIBUTE ramstyle OF i_line : SIGNAL IS "no_rw_check"; + SIGNAL i_ohsize,i_ovsize : uint12; + SIGNAL i_vdivi : unsigned(11 DOWNTO 0); + SIGNAL i_vdivr : unsigned(23 DOWNTO 0); + SIGNAL i_div : unsigned(15 DOWNTO 0); + SIGNAL i_dir : unsigned(11 DOWNTO 0); + SIGNAL i_h_frac,i_v_frac : unsigned(11 DOWNTO 0); + SIGNAL i_hacc,i_vacc : uint12; + SIGNAL i_hdown,i_vdown : std_logic; + SIGNAL i_divcpt : natural RANGE 0 TO 36; + SIGNAL i_lwad,i_lrad : natural RANGE 0 TO OHRES-1; + SIGNAL i_lwr : std_logic; + SIGNAL i_lpush,i_bil : std_logic; + SIGNAL i_ldw,i_ldrm : type_pix; + SIGNAL i_hpixp,i_hpix0,i_hpix1,i_hpix2,i_hpix3,i_hpix4 : type_pix; + SIGNAL i_hpix,i_pix : type_pix; + SIGNAL i_hnp1,i_hnp2,i_hnp3,i_hnp4 : std_logic; + SIGNAL i_ven1,i_ven2,i_ven3,i_ven4,i_ven5,i_ven6,i_ven7 : std_logic; + + SIGNAL i_htotal,i_hsstart,i_hsend : uint12; + SIGNAL i_vtotal,i_vsstart,i_vsend : uint12; + + ---------------------------------------------------------- + -- Avalon + TYPE type_avl_state IS (sIDLE,sWRITE,sREAD); + SIGNAL avl_state : type_avl_state; + SIGNAL avl_write_i,avl_write_sync,avl_write_sync2 : std_logic; + SIGNAL avl_read_i,avl_read_sync,avl_read_sync2 : std_logic; + SIGNAL avl_read_pulse,avl_write_pulse : std_logic; + SIGNAL avl_reading : std_logic; + SIGNAL avl_read_sr,avl_write_sr,avl_read_clr,avl_write_clr : std_logic; + SIGNAL avl_rad,avl_rad_c,avl_wad : natural RANGE 0 TO 2*BLEN-1; + SIGNAL avl_walt : std_logic; + SIGNAL avl_dw,avl_dr : unsigned(N_DW-1 DOWNTO 0); + SIGNAL avl_wr : std_logic; + SIGNAL avl_readack : std_logic; + SIGNAL avl_radrs,avl_wadrs : unsigned(31 DOWNTO 0); + SIGNAL avl_rbib : std_logic; + SIGNAL avl_i_offset,avl_o_offset : unsigned(31 DOWNTO 0); + SIGNAL avl_reset_na : std_logic; + SIGNAL avl_o_vs_sync,avl_o_vs : std_logic; + + FUNCTION buf_next(a,b : natural RANGE 0 TO 2) RETURN natural IS + BEGIN + IF (a=0 AND b=1) OR (a=1 AND b=0) THEN RETURN 2; END IF; + IF (a=1 AND b=2) OR (a=2 AND b=1) THEN RETURN 0; END IF; + RETURN 1; + END FUNCTION; + FUNCTION buf_offset(b : natural RANGE 0 TO 2) RETURN unsigned IS + BEGIN + IF b=1 THEN RETURN RAMSIZE; END IF; + IF b=2 THEN RETURN RAMSIZE(30 DOWNTO 0) & '0'; END IF; + RETURN x"00000000"; + END FUNCTION; + + ---------------------------------------------------------- + -- Output + SIGNAL o_run : std_logic; + SIGNAL o_mode,o_hmode,o_vmode : unsigned(4 DOWNTO 0); + SIGNAL o_htotal,o_hsstart,o_hsend : uint12; + SIGNAL o_hmin,o_hmax,o_hdisp : uint12; + SIGNAL o_hsize,o_vsize : uint12; + SIGNAL o_vtotal,o_vsstart,o_vsend : uint12; + SIGNAL o_vmin,o_vmax,o_vdisp : uint12; + SIGNAL o_divcpt : natural RANGE 0 TO 36; + SIGNAL o_iendframe,o_iendframe2,o_bufup : std_logic; + SIGNAL o_ibuf,o_obuf : natural RANGE 0 TO 2; + TYPE type_o_state IS (sDISP,sHSYNC,sREAD,sWAITREAD); + SIGNAL o_state : type_o_state; + SIGNAL o_copy,o_readack,o_readack_sync,o_readack_sync2 : std_logic; + SIGNAL o_copyv : unsigned(0 TO 7); + SIGNAL o_adrs : unsigned(31 DOWNTO 0); -- Avalon address + SIGNAL o_adrs_pre : natural RANGE 0 TO 32*4096-1; + SIGNAL o_adrsa : std_logic; + SIGNAL o_ad,o_ad1,o_ad2,o_ad3 : natural RANGE 0 TO 2*BLEN-1; + SIGNAL o_adturn : std_logic; + SIGNAL o_dr : unsigned(N_DW-1 DOWNTO 0); + SIGNAL o_shift : unsigned(0 TO N_DW+15); + SIGNAL o_sh,o_sh1,o_sh2,o_sh3 : std_logic; + SIGNAL o_reset_na : std_logic; + SIGNAL o_dpram : arr_dw(0 TO BLEN*2-1); + ATTRIBUTE ramstyle OF o_dpram : SIGNAL IS "no_rw_check"; + SIGNAL o_line0,o_line1,o_line2,o_line3 : arr_pix(0 TO OHRES-1); + ATTRIBUTE ramstyle OF o_line0 : SIGNAL IS "no_rw_check"; + 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_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_ivsize : uint12; + + SIGNAL o_vfrac,o_hfrac,o_hfrac1,o_hfrac2,o_hfrac3 : unsigned(11 DOWNTO 0); + SIGNAL o_hacc,o_hacc_ini,o_hacc_next,o_vacc,o_vacc_next,o_vacc_ini : natural RANGE 0 TO 2*OHRES-1; + SIGNAL o_hsv,o_vsv,o_dev,o_pev : unsigned(0 TO 5); + SIGNAL o_hsp,o_vss,o_vss1 : std_logic; + SIGNAL o_read,o_read_pre : std_logic; + SIGNAL o_readlev,o_copylev : natural RANGE 0 TO 2; + SIGNAL o_hburst,o_hbcpt : natural RANGE 0 TO 31; + SIGNAL o_fload : natural RANGE 0 TO 3; + SIGNAL o_acpt,o_acpt1,o_acpt2,o_acpt3,o_acpt4 : natural RANGE 0 TO 15; -- Alternance pixels FIFO + SIGNAL o_dshi : natural RANGE 0 TO 3; + SIGNAL o_first,o_last,o_last1,o_last2,o_last3 : std_logic; + SIGNAL o_lastt1,o_lastt2,o_lastt3 : std_logic; + SIGNAL o_alt : unsigned(3 DOWNTO 0); + SIGNAL o_hdown,o_vdown : std_logic; + SIGNAL o_primv,o_lastv,o_bibv : unsigned(0 TO 2); + SIGNAL o_bibu,o_bib : std_logic :='0'; + SIGNAL o_dcpt,o_dcpt1,o_dcpt2,o_dcpt3,o_dcpt4,o_dcpt5,o_dcpt6,o_dcpt7 : uint12; + SIGNAL o_hpix0,o_hpix1,o_hpix2,o_hpix3 : type_pix; + SIGNAL o_hpixq,o_vpixq,o_vpixq1 : arr_pix(0 TO 3); + + SIGNAL o_isyncline,o_isyncline2 : std_logic; + SIGNAL o_vpe : std_logic; + SIGNAL o_div,o_div2 : unsigned(17 DOWNTO 0); --uint12; + SIGNAL o_dir,o_dir2 : unsigned(11 DOWNTO 0); + SIGNAL o_vdivi : unsigned(11 DOWNTO 0); + SIGNAL o_vdivr : unsigned(23 DOWNTO 0); + SIGNAL o_divstart : std_logic; + SIGNAL o_divrun : std_logic; + SIGNAL o_hacpt,o_vacpt : unsigned(11 DOWNTO 0); + + SIGNAL o_llicpt,o_llisize,o_llipos : natural RANGE 0 TO 2**24-1; + SIGNAL o_llocpt,o_llosize : natural RANGE 0 TO 2**24-1; + SIGNAL o_lldiff : integer RANGE -2**23 TO 2**23-1 :=0; + SIGNAL o_llup,o_llos,o_llop : std_logic; + SIGNAL o_lltune_i : unsigned(15 DOWNTO 0); + SIGNAL o_llssh : natural RANGE 0 TO 2**24-1; + SIGNAL o_llcpt : natural RANGE 0 TO 31; + + ----------------------------------------------------------------------------- + -- ACPT 012345678901234--- 128bits DATA + -- 0 ...............RGB + -- 1 ............RGBrgb + -- 2 .........RGBrgbRGB + -- 3 ......RGBrgbRGBrgb + -- 4 ...RGBrgbRGBrgbRGB + -- 5 RGBrgbRGBrgbRGBrgb => PUSH RGBrgbRGBrgbRGBr + -- 6 .............gbRGB + -- 7 ..........gbRGBrgb + -- 8 .......gbRGBrgbRGB + -- 9 ....gbRGBrgbRGBrgb + -- 10 .gbRGBrgbRGBrgbRGB => PUSH gbRGBrgbRGBrgbRG + -- 11 ..............Brgb + -- 12 ...........BrgbRGB + -- 13 ........BrgbRGBrgb + -- 14 .....BrgbRGBrgbRGB + -- 15 ..BrgbRGBrgbRGBrgb => PUSH BrgbRGBrgbRGBrgb + + -- ACPT 012345678901234--- 64bits DATA + -- 0 ...............RGB + -- 1 ............RGBrgb + -- 2 .........RGBrgbRGB => PUSH RGBrgbRG + -- 3 ..............Brgb + -- 4 ...........BrgbRGB + -- 5 ........BrgbRGBrgb => PUSH BrgbRGBr + -- 6 .............gbRGB + --- 7 ..........gbRGBrgb => PUSH gbRGBrgb + + FUNCTION shift24_ipack(i_dw : unsigned(N_DW-1 DOWNTO 0); + acpt : natural RANGE 0 TO 15; + shift : unsigned(0 TO 119); + pix : type_pix) RETURN unsigned IS + VARIABLE dw : unsigned(N_DW-1 DOWNTO 0); + BEGIN + IF N_DW=128 THEN + IF acpt=5 THEN dw:=shift(0 TO 119) & pix.r; + ELSIF acpt=10 THEN dw:=shift(8 TO 119) & pix.r & pix.g; + ELSIF acpt=15 THEN dw:=shift(16 TO 119) & pix.r & pix.g & pix.b; + ELSE dw:=i_dw; + END IF; + ELSE -- N_DW=64 + IF (acpt MOD 8)=2 THEN dw:=shift(72 TO 119) & pix.r & pix.g; + ELSIF (acpt MOD 8)=5 THEN dw:=shift(64 TO 119) & pix.r; + ELSIF (acpt MOD 8)=7 THEN dw:=shift(80 TO 119) & pix.r & pix.g & pix.b; + ELSE dw:=i_dw; + END IF; + END IF; + RETURN dw; + END FUNCTION; + + FUNCTION shift24_inext (acpt : natural RANGE 0 TO 15) RETURN boolean IS + BEGIN + IF N_DW=128 THEN + RETURN (acpt=5 OR acpt=10 OR acpt=15); + ELSE -- N_DW=64 + RETURN ((acpt MOD 8)=2 OR (acpt MOD 8)=5 OR (acpt MOD 8)=7); + END IF; + END FUNCTION; + + ---------------------- + -- ACPT 0123456789012345 128bits DATA + -- 0 >RGBrgbRGBrgbRGBr + -- 1 rgbRGBrgbRGBr + -- 2 RGBrgbRGBr + -- 3 rgbRGBr + -- 4 RGBr + -- 5 >r gbRGBrgbRGBrgbRG + -- 6 RGBrgbRGBrgbRG + -- 7 rgbRGBrgbRG + -- 8 RGBrgbRG + -- 9 rgbRG + -- 10 >RG BrgbRGBrgbRGBrgb + -- 11 rgbRGBrgbRGBrgb + -- 12 RGBrgbRGBrgb + -- 13 rgbRGBrgb + -- 14 RGBrgb + -- 15 rgb + + -- ACPT 01234567 64bits DATA + -- 0 >RGBrgbRG + -- 1 rgbRG + -- 2 >RG BrgbRGBr + -- 3 rgbRGBr + -- 4 RGBr + -- 5 >r gbRGBrgb + -- 6 RGBrgb + -- 7 rgb + + FUNCTION shift24_opack(acpt : natural RANGE 0 TO 15; + shift : unsigned(0 TO N_DW+15); + dr : unsigned(N_DW-1 DOWNTO 0)) RETURN unsigned IS + VARIABLE shift_v : unsigned(0 TO N_DW+15); + BEGIN + IF N_DW=128 THEN + IF acpt=0 THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSIF acpt=5 THEN + shift_v:=shift(24 TO 31) & dr & dr(7 DOWNTO 0); + ELSIF acpt=10 THEN + shift_v:=shift(24 TO 39) & dr; + ELSE + shift_v:=shift(24 TO N_DW+15) & dr(23 DOWNTO 0); + END IF; + ELSE -- N_DW=64 + IF (acpt MOD 8)=0 THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSIF (acpt MOD 8)=2 THEN + shift_v:=shift(24 TO 39) & dr; + ELSIF (acpt MOD 8)=5 THEN + shift_v:=shift(24 TO 31) & dr & dr(7 DOWNTO 0); + ELSE + shift_v:=shift(24 TO N_DW+15) & dr(23 DOWNTO 0); + END IF; + END IF; + RETURN shift_v; + END FUNCTION; + + FUNCTION shift24_onext (acpt : natural RANGE 0 TO 15) RETURN boolean IS + BEGIN + IF N_DW=128 THEN + RETURN (acpt=0 OR acpt=5 OR acpt=10); + ELSE -- N_DW=64 + RETURN ((acpt MOD 8)=0 OR (acpt MOD 8)=2 OR (acpt MOD 8)=5); + END IF; + END FUNCTION; + + ----------------------------------------------------------------------------- + FUNCTION altx (a : unsigned(1 DOWNTO 0)) RETURN unsigned IS + BEGIN + CASE a IS + WHEN "00" => RETURN "0001"; + WHEN "01" => RETURN "0010"; + WHEN "10" => RETURN "0100"; + WHEN OTHERS => RETURN "1000"; + END CASE; + END FUNCTION; + + ----------------------------------------------------------------------------- + FUNCTION bound(a : unsigned; + s : natural) RETURN unsigned IS + BEGIN + IF a(a'left)='1' THEN + RETURN x"00"; + ELSIF a(a'left DOWNTO s)/=0 THEN + RETURN x"FF"; + ELSE + RETURN a(s-1 DOWNTO s-8); + END IF; + END FUNCTION bound; + + ----------------------------------------------------------------------------- + -- Nearest + FUNCTION near_frac(f : unsigned) RETURN unsigned IS + VARIABLE x : unsigned(FRAC-1 DOWNTO 0); + BEGIN + x:=(OTHERS =>f(f'left)); + RETURN x; + END FUNCTION; + + SIGNAL o_h_frac2,o_v_frac : unsigned(FRAC-1 DOWNTO 0); + SIGNAL o_h_bil_pix,o_v_bil_pix : type_pix; + + ----------------------------------------------------------------------------- + -- Nearest + Bilinear + Sharp Bilinear + FUNCTION bil_frac(f : unsigned) RETURN unsigned IS + BEGIN + RETURN f(f'left DOWNTO f'left+1-FRAC); + END FUNCTION; + + TYPE type_bil_t IS RECORD + r,g,b : unsigned(8+FRAC DOWNTO 0); + END RECORD; + FUNCTION bil_calc(f : unsigned(FRAC-1 DOWNTO 0); + p : arr_pix(0 TO 3)) RETURN type_bil_t IS + VARIABLE fp,fn : unsigned(FRAC DOWNTO 0); + VARIABLE u : unsigned(8+FRAC DOWNTO 0); + VARIABLE x : type_bil_t; + CONSTANT Z : unsigned(FRAC-1 DOWNTO 0):=(OTHERS =>'0'); + BEGIN + fp:='0' & f; + fn:=('1' & Z) - fp; + u:=p(2).r * fp + p(1).r * fn; + x.r:=u; + u:=p(2).g * fp + p(1).g * fn; + x.g:=u; + u:=p(2).b * fp + p(1).b * fn; + x.b:=u; + RETURN x; + END FUNCTION; + SIGNAL o_h_bil_t,o_v_bil_t : type_bil_t; + SIGNAL i_h_bil_t,i_v_bil_t : type_bil_t; + + ----------------------------------------------------------------------------- + -- Sharp Bilinear + -- <0.5 : x*x*x*4 + -- >0.5 : 1 - (1-x)*(1-x)*(1-x)*4 + + TYPE type_sbil_tt IS RECORD + f : unsigned(FRAC-1 DOWNTO 0); + s : unsigned(FRAC-1 DOWNTO 0); + END RECORD; + + SIGNAL o_h_sbil_t,o_v_sbil_t : type_sbil_tt; + + FUNCTION sbil_frac1(f : unsigned(11 DOWNTO 0)) RETURN type_sbil_tt IS + VARIABLE u : unsigned(FRAC-1 DOWNTO 0); + VARIABLE v : unsigned(2*FRAC-1 DOWNTO 0); + VARIABLE x : type_sbil_tt; + BEGIN + IF f(11)='0' THEN + u:=f(11 DOWNTO 12-FRAC); + ELSE + u:=NOT f(11 DOWNTO 12-FRAC); + END IF; + v:=u*u; + x.f:=u; + x.s:=v(2*FRAC-2 DOWNTO FRAC-1); + RETURN x; + END FUNCTION; + + FUNCTION sbil_frac2(f : unsigned(11 DOWNTO 0); + t : type_sbil_tt) RETURN unsigned IS + VARIABLE v : unsigned(2*FRAC-1 DOWNTO 0); + BEGIN + v:=t.f*t.s; + IF f(11)='0' THEN + RETURN v(2*FRAC-2 DOWNTO FRAC-1); + ELSE + RETURN NOT v(2*FRAC-2 DOWNTO FRAC-1); + END IF; + END FUNCTION; + + ----------------------------------------------------------------------------- + -- Bicubic + TYPE type_bic_abcd IS RECORD + a : unsigned(7 DOWNTO 0); -- 0.8 + b : signed(8 DOWNTO 0); -- 0.9 + c : signed(11 DOWNTO 0); -- 3.9 + d : signed(10 DOWNTO 0); -- 2.9 + xx : signed(8 DOWNTO 0); -- X.X 1.8 + END RECORD; + TYPE type_bic_pix_abcd IS RECORD + r,g,b : type_bic_abcd; + END RECORD; + TYPE type_bic_tt1 IS RECORD -- Intermediate result + r_bx,g_bx,b_bx : signed(8 DOWNTO 0); -- B.X 1.8 + r_cxx,g_cxx,b_cxx : signed(11 DOWNTO 0); -- C.XX 3.9 + r_dxx,g_dxx,b_dxx : signed(10 DOWNTO 0); -- D.XX 2.9 + END RECORD; + TYPE type_bic_tt2 IS RECORD -- Intermediate result + r_abxcxx,g_abxcxx,b_abxcxx : signed(9 DOWNTO 0); -- A + B.X + C.XX 2.8 + r_dxxx,g_dxxx,b_dxxx : signed(9 DOWNTO 0); -- D.X.X.X 2.8 + END RECORD; + + ---------------------------------------------------------- + -- Y = A + B.X + C.X.X + D.X.X.X = A + X.(B + X.(C + X.D)) + -- A = Y(0) 0 .. 1 unsigned + -- B = Y(1)/2 - Y(-1)/2 -1/2 .. +1/2 signed + -- C = Y(-1) - 5*Y(0)/2 + 2*Y(1) - Y(2)/2 -3 .. +3 signed + -- D = -Y(-1)/2 + 3*Y(0)/2 - 3*Y(1)/2 + Y(2)/2 -2 .. +2 signed + + FUNCTION bic_calc0(f : unsigned(11 DOWNTO 0); + pm,p0,p1,p2 : unsigned(7 DOWNTO 0)) RETURN type_bic_abcd IS + VARIABLE xx : signed(2*FRAC+1 DOWNTO 0); -- 2.(2*FRAC) + BEGIN + xx := signed('0' & f(11 DOWNTO 12-FRAC)) * + signed('0' & f(11 DOWNTO 12-FRAC)); -- 2.(2*FRAC) + RETURN type_bic_abcd'( + a=>p0,-- 0.8 + b=>signed(('0' & p1) - ('0' & pm)), -- 0.9 + c=>signed(("000" & pm & '0') - ("00" & p0 & "00") - ("0000" & p0) + + ("00" & p1 & "00") - ("0000" & p2)), -- 3.9 + d=>signed(("00" & p0 & '0') - ("00" & p1 & '0') - ("000" & p1) + + ("000" & p0) + ("000" & p2) - ("000" & pm)), -- 2.9 + xx=>xx(2*FRAC DOWNTO 2*FRAC-8)); -- 1.8 + END FUNCTION; + FUNCTION bic_calc0(f : unsigned(11 DOWNTO 0); + p : arr_pix(0 TO 3)) RETURN type_bic_pix_abcd IS + BEGIN + RETURN type_bic_pix_abcd'(r=>bic_calc0(f,p(0).r,p(1).r,p(2).r,p(3).r), + g=>bic_calc0(f,p(0).g,p(1).g,p(2).g,p(3).g), + b=>bic_calc0(f,p(0).b,p(1).b,p(2).b,p(3).b)); + END FUNCTION; + + ---------------------------------------------------------- + -- Calc : B.X, C.XX, D.XX + FUNCTION bic_calc1(f : unsigned(11 DOWNTO 0); + abcd : type_bic_pix_abcd) RETURN type_bic_tt1 IS + VARIABLE t : type_bic_tt1; + VARIABLE bx : signed(9+FRAC DOWNTO 0); -- 1.(FRAC+9) + VARIABLE cxx : signed(20 DOWNTO 0); -- 4.17 + VARIABLE dxx : signed(19 DOWNTO 0); -- 3.17 + BEGIN + bx := abcd.r.b * signed('0' & f(11 DOWNTO 12-FRAC)); -- 1.(FRAC+9) + t.r_bx:=bx(9+FRAC DOWNTO 9+FRAC-8); -- 1.8 + cxx:= abcd.r.c * abcd.r.xx; -- 3.9 * 1.8 = 4.17 + t.r_cxx:=cxx(19 DOWNTO 8); -- 3.9 + dxx:= abcd.r.d * abcd.r.xx; -- 2.9 * 1.8 = 3.17 + t.r_dxx:=dxx(18 DOWNTO 8); -- 2.9 + bx := abcd.g.b * signed('0' & f(11 DOWNTO 12-FRAC)); -- 1.(FRAC+9) + t.g_bx:=bx(9+FRAC DOWNTO 9+FRAC-8); -- 1.8 + cxx:= abcd.g.c * abcd.g.xx; -- 3.9 * 1.8 = 4.17 + t.g_cxx:=cxx(19 DOWNTO 8); -- 3.9 + dxx:= abcd.g.d * abcd.g.xx; -- 2.9 * 1.8 = 3.17 + t.g_dxx:=dxx(18 DOWNTO 8); -- 2.9 + bx := abcd.b.b * signed('0' & f(11 DOWNTO 12-FRAC)); -- 1.(FRAC+9) + t.b_bx:=bx(9+FRAC DOWNTO 9+FRAC-8); -- 1.8 + cxx:= abcd.b.c * abcd.b.xx; -- 3.9 * 1.8 = 4.17 + t.b_cxx:=cxx(19 DOWNTO 8); -- 3.9 + dxx:= abcd.b.d * abcd.b.xx; -- 2.9 * 1.8 = 3.17 + t.b_dxx:=dxx(18 DOWNTO 8); -- 2.9 + RETURN t; + END FUNCTION; + + ---------------------------------------------------------- + -- Calc A + BX + CXX , X.DXX + FUNCTION bic_calc2(f : unsigned(11 DOWNTO 0); + t : type_bic_tt1; + abcd : type_bic_pix_abcd) RETURN type_bic_tt2 IS + VARIABLE u : type_bic_tt2; + VARIABLE x : signed(11+FRAC DOWNTO 0); -- 3.(9+FRAC) + BEGIN + u.r_abxcxx:=(t.r_bx(8) & t.r_bx) + ("00" & signed(abcd.r.a)) + t.r_cxx(10 DOWNTO 1); -- 2.8 + u.g_abxcxx:=(t.g_bx(8) & t.g_bx) + ("00" & signed(abcd.g.a)) + t.g_cxx(10 DOWNTO 1); -- 2.8 + u.b_abxcxx:=(t.b_bx(8) & t.b_bx) + ("00" & signed(abcd.b.a)) + t.b_cxx(10 DOWNTO 1); -- 2.8 + + x:=t.r_dxx * signed('0' & f(11 DOWNTO 12-FRAC)); --2.9 * 1.FRAC =3.(9+FRAC) + u.r_dxxx:=x(10+FRAC DOWNTO 9+FRAC-8); -- 2.8 + x:=t.g_dxx * signed('0' & f(11 DOWNTO 12-FRAC)); --2.9 * 1.FRAC =3.(9+FRAC) + u.g_dxxx:=x(10+FRAC DOWNTO 9+FRAC-8); -- 2.8 + x:=t.b_dxx * signed('0' & f(11 DOWNTO 12-FRAC)); --2.9 * 1.FRAC =3.(9+FRAC) + u.b_dxxx:=x(10+FRAC DOWNTO 9+FRAC-8); -- 2.8 + RETURN u; + END FUNCTION; + + ---------------------------------------------------------- + -- Calc (A + BX + CXX) + (DXXX) + FUNCTION bic_calc3(f : unsigned(11 DOWNTO 0); + t : type_bic_tt2; + abcd : type_bic_pix_abcd) RETURN type_pix IS + VARIABLE x : type_pix; + VARIABLE v : signed(9 DOWNTO 0); -- 2.8 + BEGIN + v:=t.r_abxcxx + t.r_dxxx; + x.r:=bound(unsigned(v),8); + v:=t.g_abxcxx + t.g_dxxx; + x.g:=bound(unsigned(v),8); + v:=t.b_abxcxx + t.b_dxxx; + x.b:=bound(unsigned(v),8); + RETURN x; + END FUNCTION; + + ----------------------------------------------------------------------------- + SIGNAL o_h_bic_pix,o_v_bic_pix : type_pix; + SIGNAL o_h_bic_abcd1,o_h_bic_abcd2 : type_bic_pix_abcd; + SIGNAL o_v_bic_abcd1,o_v_bic_abcd2 : type_bic_pix_abcd; + SIGNAL o_h_bic_tt1,o_v_bic_tt1 : type_bic_tt1; + SIGNAL o_h_bic_tt2,o_v_bic_tt2 : type_bic_tt2; + + ----------------------------------------------------------------------------- + -- Polyphase + + TYPE arr_uv36 IS ARRAY (natural RANGE <>) OF unsigned(35 DOWNTO 0); -- 9/9/9/9 + TYPE arr_int9 IS ARRAY (natural RANGE <>) OF integer RANGE -256 TO 255; + CONSTANT POLY16 : arr_int9 := ( + -24,-20,-16,-11,-6,-1,2,5,6,6,5,4,2,1,0,0, + 176,174,169,160,147,129,109,84,58,22,3,-12,-20,-25,-26,-25, + -24,-26,-26,-23,-16,-4,11,32,58,96,119,140,154,165,172,175, + 0,0,1,2,3,4,6,7,6,4,1,-4,-8,-13,-18,-22); + + 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); + END RECORD; + + SIGNAL o_h_poly_t,o_v_poly_t : type_poly_t; + + FUNCTION poly_calc1(fi : unsigned(35 DOWNTO 0); + 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)); + RETURN t; + END FUNCTION; + + FUNCTION poly_calc2(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); + RETURN p; + END FUNCTION; + + ----------------------------------------------------------------------------- + -- DEBUG + + SIGNAL o_debug_set : std_logic; + SIGNAL o_debug_col : unsigned(7 DOWNTO 0); + SIGNAL o_debug_vin0 : unsigned(0 TO 32*5-1) :=(OTHERS =>'0'); + SIGNAL o_debug_vin1 : unsigned(0 TO 32*5-1) :=(OTHERS =>'0'); + SIGNAL o_debug_hcpt2,o_debug_hcpt3,o_debug_hcpt4 : uint12; + SIGNAL o_debug_hcpt5,o_debug_hcpt6 : uint12; + + SIGNAL o_debug_char : unsigned(4 DOWNTO 0); + SIGNAL o_debug_hchar : natural RANGE 0 TO 255; + + FUNCTION CC(i : character) RETURN unsigned IS + BEGIN + CASE i IS + WHEN '0' => RETURN "00000"; + WHEN '1' => RETURN "00001"; + WHEN '2' => RETURN "00010"; + WHEN '3' => RETURN "00011"; + WHEN '4' => RETURN "00100"; + WHEN '5' => RETURN "00101"; + WHEN '6' => RETURN "00110"; + WHEN '7' => RETURN "00111"; + WHEN '8' => RETURN "01000"; + WHEN '9' => RETURN "01001"; + WHEN 'A' => RETURN "01010"; + WHEN 'B' => RETURN "01011"; + WHEN 'C' => RETURN "01100"; + WHEN 'D' => RETURN "01101"; + WHEN 'E' => RETURN "01110"; + WHEN 'F' => RETURN "01111"; + WHEN ' ' => RETURN "10000"; + WHEN '=' => RETURN "10001"; + WHEN '+' => RETURN "10010"; + WHEN '-' => RETURN "10011"; + WHEN '<' => RETURN "10100"; + WHEN '>' => RETURN "10101"; + WHEN '^' => RETURN "10110"; + WHEN 'v' => RETURN "10111"; + WHEN '(' => RETURN "11000"; + WHEN ')' => RETURN "11001"; + WHEN ':' => RETURN "11010"; + WHEN '.' => RETURN "11011"; + WHEN ',' => RETURN "11100"; + WHEN '?' => RETURN "11101"; + WHEN '|' => RETURN "11110"; + WHEN '#' => RETURN "11111"; + WHEN OTHERS => RETURN "10000"; + END CASE; + END FUNCTION CC; + FUNCTION CS(s : string) RETURN unsigned IS + VARIABLE r : unsigned(0 TO s'length*5-1); + VARIABLE j : natural :=0; + BEGIN + FOR i IN s'RANGE LOOP + r(j TO j+4) :=CC(s(i)); + j:=j+5; + END LOOP; + RETURN r; + END FUNCTION CS; + FUNCTION CN(v : unsigned) RETURN unsigned IS + VARIABLE t : unsigned(0 TO v'length-1); + VARIABLE o : unsigned(0 TO v'length/4*5-1); + BEGIN + t:=v; + FOR i IN 0 TO v'length/4-1 LOOP + o(i*5 TO i*5+4):='0' & t(i*4 TO i*4+3); + END LOOP; + RETURN o; + END FUNCTION CN; + +BEGIN + + ----------------------------------------------------------------------------- + i_reset_na<='0' WHEN reset_na='0' ELSE '1' WHEN rising_edge(i_clk); + o_reset_na<='0' WHEN reset_na='0' ELSE '1' WHEN rising_edge(o_clk); + avl_reset_na<='0' WHEN reset_na='0' ELSE '1' WHEN rising_edge(avl_clk); + + ----------------------------------------------------------------------------- + -- Input pixels FIFO and shreg + InAT:PROCESS(i_clk,i_reset_na) IS + CONSTANT Z : unsigned(FRAC-1 DOWNTO 0):=(OTHERS =>'0'); + VARIABLE frac_v : unsigned(FRAC-1 DOWNTO 0); + VARIABLE div_v : unsigned(15 DOWNTO 0); + VARIABLE dir_v : unsigned(11 DOWNTO 0); + BEGIN + IF i_reset_na='0' THEN + i_write_pre<='0'; + + ELSIF rising_edge(i_clk) THEN + i_push<='0'; + i_eol<='0'; -- End Of Line + i_freeze <=freeze; -- + i_iauto<=iauto; -- ? + + ------------------------------------------------------ + i_head(127 DOWNTO 120)<=x"01"; -- Header type + i_head(119 DOWNTO 112)<=x"01"; -- 24bits/pixels, packed RGB, big endian + i_head(111 DOWNTO 96)<=to_unsigned(N_BURST,16); -- Header size + i_head(95 DOWNTO 80)<=x"0000"; -- Attributes. TBD + i_head(80)<=i_inter; + i_head(81)<=i_fl; + i_head(82)<=i_hdown; + i_head(83)<=i_vdown; + i_head(79 DOWNTO 64)<=to_unsigned(i_hrsize,16); -- Image width + i_head(63 DOWNTO 48)<=to_unsigned(i_vrsize,16); -- Image height + i_head(47 DOWNTO 32)<= + to_unsigned(N_BURST * i_hburst,16); -- Line Length. Bytes + i_head(31 DOWNTO 0)<=x"0000_0000"; -- TBD + + ------------------------------------------------------ + IF i_ce='1' THEN + ---------------------------------------------------- + i_hs_pre<=i_hs; + i_vs_pre<=i_vs; + i_de_pre<=i_de; + i_fl_pre<=i_fl; + + ---------------------------------------------------- + -- Detect interlaced video + IF NOT INTER THEN + i_intercnt<=0; + ELSIF i_fl/=i_fl_pre THEN + i_intercnt<=3; + ELSIF i_vs='1' AND i_vs_pre='0' AND i_intercnt>0 THEN + i_intercnt<=i_intercnt-1; + END IF; + i_inter<=to_std_logic(i_intercnt>0); + + ---------------------------------------------------- + IF i_vs='1' AND i_vs_pre='0' THEN + i_sof<='1'; + END IF; + + IF i_de='1' AND i_sof='1' THEN + i_sof<='0'; + i_vcpt<=0; + IF i_inter='1' AND i_flm='1' AND i_half='0' AND INTER THEN + i_adrsi<=to_unsigned(N_BURST * i_hburst,32) + + to_unsigned(N_BURST * to_integer( + unsigned'("00") & to_std_logic(HEADER)),32); + ELSE + i_adrsi<=to_unsigned(N_BURST * to_integer( + unsigned'("00") & to_std_logic(HEADER)),32); + END IF; + END IF; + + IF i_de='1' THEN + i_flm<=NOT i_fl; + END IF; + + i_ven<=to_std_logic(i_hcpt>=i_hmin AND i_hcpt<=i_hmax+1 AND + i_vcpt>=i_vmin AND i_vcpt<=i_vmax AND i_de='1'); + + -- Detects end of frame for triple buffering. + -- Waits for second frame of interlaced video + i_endframe<=to_std_logic(i_vcpt=i_vmax + 1 AND + (i_inter='0' OR i_fl='1')); + -- Detects third line for low lag mode + i_syncline<=to_std_logic(i_vcpt=i_vmin + 3); + + ---------------------------------------------------- + IF i_de='1' AND i_de_pre='0' THEN + i_vimaxc<=i_vcpt; + i_hcpt<=0; + ELSE + i_hcpt<=(i_hcpt+1) MOD 4096; + END IF; + + IF i_de='0' AND i_de_pre='1' THEN + i_himax<=i_hcpt; + END IF; + + IF i_vs='1' THEN + i_vimax<=i_vimaxc; + END IF; + + IF i_iauto='1' THEN + -- Auto-size + i_hmin<=0; + i_hmax<=i_himax; + i_vmin<=0; + IF i_inter='0' OR i_fl='0' THEN + i_vmax<=i_vimax; + END IF; + ELSE + -- Forced image + i_hmin<=himin; -- + i_hmax<=himax; -- + i_vmin<=vimin; -- + i_vmax<=vimax; -- + END IF; + + ---------------------------------------------------- + -- TEST : Scan image properties + IF i_hs='1' AND i_hs_pre='0' AND i_vcpt=1 THEN i_hsstart<=i_hcpt+1; END IF; + IF i_hs='0' AND i_hs_pre='1' AND i_vcpt=1 THEN i_hsend<=i_hcpt+1; END IF; + IF i_de='1' AND i_de_pre='0' AND i_vcpt=1 THEN i_htotal<=i_hcpt+1; END IF; + + IF i_vs='1' AND i_vs_pre='0' THEN i_vsstart<=i_vcpt; END IF; + IF i_vs='0' AND i_vs_pre='1' THEN i_vsend<=i_vcpt; END IF; + IF i_de='1' AND i_sof='1' THEN i_vtotal<=i_vcpt; END IF; + + ---------------------------------------------------- + i_mode<=mode; -- + + -- Downscaling : Nearest or bilinear + i_bil<=to_std_logic(i_mode(2 DOWNTO 0)/="000" AND DOWNSCALE); + + 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 + + ---------------------------------------------------- + i_hsize <=(4096+i_hmax-i_hmin+1) MOD 4096; + i_vmaxmin<=(4096+i_vmax-i_vmin+1) MOD 4096; + + IF i_inter='0' THEN + -- Non interlaced + i_vsize<=i_vmaxmin; + i_half<='0'; + ELSIF i_ovsize<2*i_vmaxmin THEN + -- Interlaced, but downscaling, use only half frames + i_vsize<=i_vmaxmin; + i_half<='1'; + ELSE + -- Interlaced : Double image height + i_vsize<=2*i_vmaxmin; + i_half<='0'; + END IF; + + i_ohsize<=o_hsize; -- + i_ovsize<=o_vsize; -- + + ---------------------------------------------------- + -- Downscaling vertical + i_divstart<='0'; + IF i_hs_delay=14 THEN + IF i_vacc + i_ovsize < i_vsize THEN + i_vacc<=(i_vacc + i_ovsize) MOD 4096; + i_vnp<='0'; + ELSE + i_vacc<=(i_vacc + i_ovsize - i_vsize + 4096) MOD 4096; + i_vnp<='1'; + END IF; + i_divstart<='1'; + + IF i_vcpt=i_vmin THEN + i_vacc<=i_ovsize/2 + i_vsize/2; + i_vnp<='0'; -- + END IF; + END IF; + + IF i_vdown='0' THEN + i_vnp<='1'; + END IF; + + -- Downscaling horizontal + IF i_ven='1' THEN + IF i_hacc + i_ohsize < i_hsize THEN + i_hacc<=(i_hacc + i_ohsize) MOD 4096; + i_hnp<='0'; + ELSE + i_hacc<=(i_hacc + i_ohsize - i_hsize + 4096) MOD 4096; + i_hnp<='1'; + END IF; + END IF; + IF i_hdown='0' THEN + i_hnp<='1'; + END IF; + + ---------------------------------------------------- + -- Downscaling interpolation + i_hpixp<=(i_r,i_g,i_b); + i_hpix0<=i_hpixp; + i_hpix1<=i_hpix0; + i_hpix2<=i_hpix1; + i_hpix3<=i_hpix2; + i_hpix4<=i_hpix3; + + i_hnp1<=i_hnp; i_hnp2<=i_hnp1; i_hnp3<=i_hnp2; i_hnp4<=i_hnp3; + i_ven1<=i_ven; i_ven2<=i_ven1; i_ven3<=i_ven2; i_ven4<=i_ven3; + i_ven5<=i_ven4; i_ven6<=i_ven5; i_ven7<=i_ven6; + + -- C1 : DIV 1. Pipelined 4 bits non-restoring divider + dir_v:=x"000"; + div_v:=to_unsigned(i_hacc * 16,16); + + div_v:=div_v-to_unsigned(i_hsize*8,16); + dir_v(11):=NOT div_v(15); + IF div_v(15)='0' THEN + div_v:=div_v-to_unsigned(i_hsize*4,16); + ELSE + div_v:=div_v+to_unsigned(i_hsize*4,16); + END IF; + dir_v(10):=NOT div_v(15); + i_div<=div_v; + i_dir<=dir_v; + + -- C2 : DIV 2. + div_v:=i_div; + dir_v:=i_dir; + IF div_v(15)='0' THEN + div_v:=div_v-to_unsigned(i_hsize*2,16); + ELSE + div_v:=div_v+to_unsigned(i_hsize*2,16); + END IF; + dir_v(9):=NOT div_v(15); + + IF div_v(15)='0' THEN + div_v:=div_v-to_unsigned(i_hsize,16); + ELSE + div_v:=div_v+to_unsigned(i_hsize,16); + END IF; + dir_v(8):=NOT div_v(15); + i_h_frac<=dir_v; + + -- C4 : Horizontal Bilinear + IF i_bil='0' THEN + frac_v:=near_frac(i_h_frac); + ELSE + frac_v:=bil_frac(i_h_frac); + END IF; + + i_h_bil_t<=bil_calc(frac_v,(i_hpix3,i_hpix3,i_hpix4,i_hpix4)); + 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); + + IF i_hdown='0' THEN + i_hpix<=i_hpix4; + END IF; + + -- C5 : Vertical Bilinear + IF i_bil='0' THEN + frac_v:=near_frac(i_v_frac(11 DOWNTO 0)); + ELSE + frac_v:=bil_frac(i_v_frac(11 DOWNTO 0)); + END IF; + + i_v_bil_t<=bil_calc(frac_v,(i_hpix,i_hpix,i_ldrm,i_ldrm)); + i_pix.r<=bound(i_v_bil_t.r,8+FRAC); + i_pix.g<=bound(i_v_bil_t.g,8+FRAC); + i_pix.b<=bound(i_v_bil_t.b,8+FRAC); + + IF i_vdown='0' THEN + i_pix<=i_hpix; + END IF; + + ---------------------------------------------------- + -- VNP : Vert. downscaling line enable + -- HNP : Horiz. downscaling pix. enable + -- VEN : Enable pixel within displayed window + + IF (i_hnp4='1' AND i_ven6='1') OR i_pushend='1' THEN + i_shift<=i_shift(24 TO 119) & i_pix.r & i_pix.g & i_pix.b; + i_dw<=shift24_ipack(i_dw,i_acpt,i_shift,i_pix); + IF i_pushhead='1' THEN + i_dw<=i_head; + END IF; + + IF shift24_inext(i_acpt) AND i_vnp='1' THEN + i_push<='1'; + i_pushend<='0'; + END IF; + i_acpt<=(i_acpt+1) MOD 16; + END IF; + + IF i_ven6='1' AND i_ven5='0' AND i_vnp='1' THEN + i_pushend<='1'; + END IF; + i_pushend2<=i_pushend; + + IF ((i_ven6='0' AND i_ven7='1') OR i_pushend2='1')AND i_pushend='0' THEN + i_eol<='1'; + END IF; + + -- Delay I_HS raising for a few cycles, finish ongoing mem. access + IF i_hs='1' AND i_hs_pre='0' THEN + i_hs_delay<=0; + ELSIF i_hs_delay<15 THEN + i_hs_delay<=i_hs_delay+1; + END IF; + + IF i_hs_delay=14 THEN -- i_hs='1' AND i_hs_pre='0' THEN + i_acpt<=0; + i_hacc<=i_ohsize/2 + i_hsize/2; + i_lwad<=0; + i_lrad<=0; + i_wad<=2*BLEN-1; + i_vcpt<=i_vcpt+1; + i_hbcpt<=0; -- Bursts per line counter + IF i_vnp='1' AND i_hbcpt>0 AND i_hbfix='0' THEN + i_hburst<=i_hbcpt; + i_hbfix<='1'; + END IF; + END IF; + + IF i_vs='0' AND i_vs_pre='1' THEN + i_vacc<=i_ovsize/2 + i_vsize/2; + -- Push header + i_pushhead<=to_std_logic(HEADER); + i_hbfix<='0'; + END IF; + + END IF; -- IF i_ce='1' + + ------------------------------------------------------ + -- Push pixels to downscaling line buffer + i_lwr<=i_hnp4 AND i_ven5; + IF i_lwr='1' THEN + i_lwad<=(i_lwad+1) MOD OHRES; + END IF; + i_ldw<=i_hpix; + + IF i_hnp3='1' AND i_ven4='1' THEN + i_lrad<=(i_lrad+1) MOD OHRES; + END IF; + + ------------------------------------------------------ + -- Push pixels to DPRAM + i_wr<='0'; + + IF i_push='1' AND i_freeze='0' THEN + i_wr<='1'; + i_wad<=(i_wad+1) MOD (BLEN*2); + IF ((i_wad+1) MOD BLEN=BLEN-1) THEN + i_hbcpt<=(i_hbcpt+1) MOD 32; + i_write_pre<=NOT i_write_pre; + IF (i_wad+1)/BLEN=0 THEN + i_walt<='0'; + ELSE + i_walt<='1'; + END IF; + i_adrs<=i_adrsi; + i_adrsi<=i_adrsi+N_BURST; + END IF; + END IF; + + IF i_pushhead='1' AND i_freeze='0' THEN + i_wr<='1'; + i_wad<=0; + i_write_pre<=NOT i_write; + i_walt<='0'; + i_adrs<=(OTHERS =>'0'); + i_pushhead<='0'; + END IF; + + -- Delay a bit EOL : Async. AVL/I clocks... + i_eol2<=i_eol; i_eol3<=i_eol2; i_eol4<=i_eol3; + + -- End of line + IF i_eol4='1' AND i_freeze='0' THEN + IF (i_wad MOD BLEN)/=BLEN-1 THEN + -- Some pixels are in the partially filled buffer + i_hbcpt<=(i_hbcpt+1) MOD 32; + i_write_pre<=NOT i_write_pre; + IF i_wad/BLEN=0 THEN + i_walt<='0'; + ELSE + i_walt<='1'; + END IF; + i_adrs<=i_adrsi; + IF i_inter='1' AND i_half='0' THEN + -- Skip every other line for interlaced video + i_adrsi<=i_adrsi + N_BURST * (i_hburst + 1); + ELSE + i_adrsi<=i_adrsi + N_BURST; + END IF; + ELSE + IF i_inter='1' AND i_half='0' THEN + -- Skip every other line for interlaced video + i_adrsi<=i_adrsi + N_BURST * i_hburst; + END IF; + END IF; + END IF; + i_write<=i_write_pre AND NOT i_freeze; + + END IF; + END PROCESS; + + -- If downscaling, export to the output part the downscaled size + i_hrsize<=i_hsize WHEN i_hdown='0' ELSE i_ohsize; + i_vrsize<=i_vsize WHEN i_vdown='0' ELSE i_ovsize; + + ----------------------------------------------------------------------------- + -- Input Dividers. For downscaling. + + -- Hdiv = 1 / IHsize 1.12 / 12 --> 0.12 + -- Vfrac = IVacc / IVsize 12 / 12 --> 12 + + -- Division + IDividers:PROCESS (i_clk,i_reset_na) IS + BEGIN + IF i_reset_na='0' THEN +--pragma synthesis_off + i_v_frac<=x"000"; +--pragma synthesis_on + NULL; + ELSIF rising_edge(i_clk) THEN + i_vdivi<=to_unsigned(i_vsize,12); + i_vdivr<=to_unsigned(i_vacc*4096,24); + + ------------------------------------------------------ + IF i_divstart='1' THEN + i_divcpt<=0; + i_divrun<='1'; + + ELSIF i_divrun='1' THEN + ---------------------------------------------------- + IF i_divcpt=12 THEN + i_divrun<='0'; + i_v_frac<=i_vdivr(10 DOWNTO 0) & NOT i_vdivr(23); + ELSE + i_divcpt<=i_divcpt+1; + END IF; + + IF i_vdivr(23)='0' THEN + i_vdivr(23 DOWNTO 12)<=i_vdivr(22 DOWNTO 11) - i_vdivi; + ELSE + i_vdivr(23 DOWNTO 12)<=i_vdivr(22 DOWNTO 11) + i_vdivi; + END IF; + i_vdivr(11 DOWNTO 0)<=i_vdivr(10 DOWNTO 0) & NOT i_vdivr(23); + + ---------------------------------------------------- + END IF; + END IF; + END PROCESS IDividers; + + ----------------------------------------------------------------------------- + -- DPRAM INPUT + + PROCESS (i_clk) IS + BEGIN + IF rising_edge(i_clk) THEN + IF i_wr='1' THEN + i_dpram(i_wad)<=i_dw; + END IF; + END IF; + END PROCESS; + + avl_dr<=i_dpram(avl_rad_c) WHEN rising_edge(avl_clk); + + -- Line buffer for downscaling with interpolation + DownLine:IF DOWNSCALE GENERATE + ILBUF:PROCESS(i_clk) IS + BEGIN + IF rising_edge(i_clk) THEN + IF i_lwr='1' THEN + i_line(i_lwad)<=i_ldw; + END IF; + + i_ldrm<=i_line(i_lrad); + END IF; + END PROCESS ILBUF; + END GENERATE DownLine; + + ----------------------------------------------------------------------------- + -- AVALON interface + Avaloir:PROCESS(avl_clk,avl_reset_na) IS + BEGIN + IF avl_reset_na='0' THEN + avl_reading<='0'; + avl_state<=sIDLE; + avl_write_sr<='0'; + avl_read_sr<='0'; + avl_readack<='0'; + + ELSIF rising_edge(avl_clk) THEN + ---------------------------------- + avl_write_sync<=i_write; -- + avl_write_sync2<=avl_write_sync; + avl_write_pulse<=avl_write_sync XOR avl_write_sync2; + avl_wadrs <=i_adrs AND (RAMSIZE - 1); -- + avl_walt <=i_walt; -- + + ---------------------------------- + avl_read_sync<=o_read; -- + avl_read_sync2<=avl_read_sync; + avl_read_pulse<=avl_read_sync XOR avl_read_sync2; + avl_rbib <=o_bib; + avl_radrs <=o_adrs AND (RAMSIZE - 1); -- + + -------------------------------------------- + avl_o_offset<=buf_offset(o_obuf); -- + avl_i_offset<=buf_offset(o_ibuf); -- + + avl_o_vs_sync<=o_vsv(0); -- + avl_o_vs<=avl_o_vs_sync; + + -------------------------------------------- + avl_dw<=unsigned(avl_readdata); + avl_read_i<='0'; + avl_write_i<='0'; + + avl_write_sr<=(avl_write_sr OR avl_write_pulse) AND NOT avl_write_clr; + avl_read_sr <=(avl_read_sr OR avl_read_pulse) AND NOT avl_read_clr; + avl_write_clr<='0'; + avl_read_clr <='0'; + + avl_rad<=avl_rad_c; + + -------------------------------------------- + CASE avl_state IS + WHEN sIDLE => + IF avl_o_vs='0' AND avl_o_vs_sync='1' THEN + avl_wad<=0; + END IF; + IF avl_write_sr='1' THEN + avl_state<=sWRITE; + avl_write_clr<='1'; + IF avl_walt='0' THEN + avl_rad<=0; + ELSE + avl_rad<=BLEN; + END IF; + ELSIF avl_read_sr='1' AND avl_reading='0' THEN + IF avl_rbib='0' THEN + avl_wad<=2*BLEN-1; + ELSE + avl_wad<=BLEN-1; + END IF; + avl_state<=sREAD; + avl_read_clr<='1'; + END IF; + + WHEN sWRITE => + avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_wadrs(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_i_offset(N_AW+NB_LA-1 DOWNTO NB_LA)); + avl_write_i<='1'; + IF avl_write_i='1' AND avl_waitrequest='0' THEN + IF (avl_rad MOD BLEN)=BLEN-1 THEN + avl_write_i<='0'; + avl_state<=sIDLE; + END IF; + END IF; + + WHEN sREAD => + avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_radrs(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_o_offset(N_AW+NB_LA-1 DOWNTO NB_LA)); + avl_read_i<='1'; + avl_reading<='1'; + IF avl_read_i='1' AND avl_waitrequest='0' THEN + avl_state<=sIDLE; + avl_read_i<='0'; + END IF; + END CASE; + + -------------------------------------------- + -- Pipelined data read + avl_wr<='0'; + IF avl_readdatavalid='1' THEN + avl_wr<='1'; + avl_wad<=(avl_wad+1) MOD (2*BLEN); + IF (avl_wad MOD BLEN)=BLEN-2 THEN + avl_reading<='0'; + avl_readack<=NOT avl_readack; + END IF; + END IF; + + -------------------------------------------- + END IF; + END PROCESS Avaloir; + + avl_read<=avl_read_i; + avl_write<=avl_write_i; + avl_writedata<=std_logic_vector(avl_dr); + avl_burstcount<=std_logic_vector(to_unsigned(BLEN,8)); + avl_byteenable<=(OTHERS =>'1'); + + avl_rad_c<=(avl_rad+1) MOD (2*BLEN) + WHEN avl_write_i='1' AND avl_waitrequest='0' ELSE avl_rad; + + ----------------------------------------------------------------------------- + -- DPRAM OUTPUT + PROCESS (avl_clk) IS + BEGIN + IF rising_edge(avl_clk) THEN + IF avl_wr='1' THEN + o_dpram(avl_wad)<=avl_dw; + END IF; + END IF; + END PROCESS; + + o_dr<=o_dpram(o_ad3) WHEN rising_edge(o_clk); + + ----------------------------------------------------------------------------- + + -- Output Vertical Divider + -- Vfrac = Vacc / Vsize + ODivider:PROCESS (o_clk,o_reset_na) IS + BEGIN + IF o_reset_na='0' THEN +--pragma synthesis_off + o_vfrac<=x"000"; +--pragma synthesis_on + ELSIF rising_edge(o_clk) THEN + o_vdivi<=to_unsigned(o_vsize,12); + o_vdivr<=to_unsigned(o_vacc*4096,24); + ------------------------------------------------------ + IF o_divstart='1' THEN + o_divcpt<=0; + o_divrun<='1'; + + ELSIF o_divrun='1' THEN + ---------------------------------------------------- + IF o_divcpt=12 THEN + o_divrun<='0'; + o_vfrac<=o_vdivr(10 DOWNTO 0) & NOT o_vdivr(23); + ELSE + o_divcpt<=o_divcpt+1; + END IF; + + IF o_vdivr(23)='0' THEN + o_vdivr(23 DOWNTO 12)<=o_vdivr(22 DOWNTO 11) - o_vdivi; + ELSE + o_vdivr(23 DOWNTO 12)<=o_vdivr(22 DOWNTO 11) + o_vdivi; + END IF; + o_vdivr(11 DOWNTO 0)<=o_vdivr(10 DOWNTO 0) & NOT o_vdivr(23); + ---------------------------------------------------- + END IF; + END IF; + END PROCESS ODivider; + + ----------------------------------------------------------------------------- + Scalaire:PROCESS (o_clk,o_reset_na) IS + VARIABLE mul_v : unsigned(47 DOWNTO 0); + VARIABLE lev_inc_v,lev_dec_v : std_logic; + VARIABLE prim_v,last_v,bib_v : std_logic; + VARIABLE shift_v : unsigned(0 TO N_DW+15); + VARIABLE hcarry_v,vcarry_v : boolean; + VARIABLE dif_v : natural RANGE 0 TO 4*OHRES-1; + BEGIN + IF o_reset_na='0' THEN + o_copy<='0'; + o_state<=sDISP; + o_read_pre<='0'; + o_readlev<=0; + o_copylev<=0; + o_hsp<='0'; + + ELSIF rising_edge(o_clk) THEN + ------------------------------------------------------ + o_mode <=mode; -- ? + o_run <=run; -- ? + + o_htotal <=htotal; -- ? + o_hsstart<=hsstart; -- ? + o_hsend <=hsend; -- ? + o_hdisp <=hdisp; -- ? + o_hmin <=hmin; -- ? + o_hmax <=hmax; -- ? + + o_vtotal <=vtotal; -- ? + o_vsstart<=vsstart; -- ? + o_vsend <=vsend; -- ? + o_vdisp <=vdisp; -- ? + o_vmin <=vmin; -- ? + o_vmax <=vmax; -- ? + + o_hsize <=o_hmax - o_hmin + 1; + o_vsize <=o_vmax - o_vmin + 1; + + -------------------------------------------- + -- Triple buffering. + -- Input : Toggle buffer at end of input frame + o_iendframe<=i_endframe; -- + o_iendframe2<=o_iendframe; + IF o_iendframe='1' AND o_iendframe2='0' THEN + o_ibuf<=buf_next(o_ibuf,o_obuf); + o_bufup<='1'; + END IF; + + -- Output : Change framebuffer, and image properties, at VS falling edge + IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup='1' THEN + o_obuf<=buf_next(o_obuf,o_ibuf); + o_bufup<='0'; + o_hburst <=i_hburst; -- Bursts per line + o_ihsize<=i_hrsize; -- + o_ivsize<=i_vrsize; -- + o_hdown<=i_hdown; -- + o_vdown<=i_vdown; -- + END IF; + + -- Triple buffer disabled + IF o_mode(3)='0' THEN + o_obuf<=0; + o_ibuf<=0; + END IF; + + ------------------------------------------------------ + o_hmode<=o_mode; + IF o_hdown='1' AND DOWNSCALE THEN + -- Force nearest if downscaling : Downscaled framebuffer + o_hmode(2 DOWNTO 0)<="000"; + END IF; + + o_vmode<=o_mode; + IF o_vdown='1' AND DOWNSCALE THEN + -- Force nearest if downscaling : Downscaled framebuffer + o_vmode(2 DOWNTO 0)<="000"; + END IF; + + ------------------------------------------------------ + -- End DRAM READ + o_readack_sync<=avl_readack; -- + o_readack_sync2<=o_readack_sync; + o_readack<=o_readack_sync XOR o_readack_sync2; + + ------------------------------------------------------ + lev_inc_v:='0'; + lev_dec_v:='0'; + + -- acpt : Pixel position within current data word + -- dcpt : Destination image position + -- hpos : Source image position, fixed point 12.12 + + -- Force preload 2 lines at top of screen + IF o_hsv(0)='1' AND o_hsv(1)='0' THEN + IF o_vcpt_pre3=o_vmin THEN + o_fload<=2; + END IF; + o_hsp<='1'; + END IF; + + o_vpe<=to_std_logic(o_vcpt_pre=o_vmin); + o_divstart<='0'; + o_adrsa<='0'; + + o_vacc_ini<=(o_vsize/2 - o_ivsize/2 + 4096) MOD 4096; + o_hacc_ini<=o_hsize/2 + o_ihsize/2; + + CASE o_state IS + -------------------------------------------------- + WHEN sDISP => + IF o_hsp='1' THEN + o_state<=sHSYNC; + o_hsp<='0'; + END IF; + + -------------------------------------------------- + WHEN sHSYNC => + dif_v:=(o_vacc_next - o_vsize + 8192) MOD 8192; + IF dif_v>=4096 THEN + o_vacc <=o_vacc_next; + o_vacc_next<=(o_vacc_next + o_ivsize) MOD 4096; + vcarry_v:=false; + ELSE + o_vacc <=dif_v; + o_vacc_next<=(dif_v + o_ivsize + 4096) MOD 4096; + vcarry_v:=true; + END IF; + o_divstart<='1'; + IF o_vcpt_pre2=o_vmin THEN --pe='0' THEN + o_vacc <=o_vacc_ini; + o_vacc_next<=o_vacc_ini + o_ivsize; + o_vacpt<=x"001"; + vcarry_v:=false; + END IF; + + IF vcarry_v THEN + o_vacpt<=o_vacpt+1; + END IF; + o_hbcpt<=0; -- Clear burst counter on line + IF (o_vpe='1' AND vcarry_v) OR o_fload>0 THEN + o_state<=sREAD; + ELSE + o_state<=sDISP; + END IF; + + WHEN sREAD => + -- Read a block + IF o_readlev<2 THEN + lev_inc_v:='1'; + o_read_pre<=NOT o_read_pre; + o_state <=sWAITREAD; + o_bibu<=NOT o_bibu; + END IF; + prim_v:=to_std_logic(o_hbcpt=0); + last_v:=to_std_logic(o_hbcpt=o_hburst-1); + bib_v :=o_bibu; + o_bib <=o_bibu; + o_adrsa<='1'; + + WHEN sWAITREAD => + IF o_readack='1' THEN + o_hbcpt<=o_hbcpt+1; + IF o_hbcpt=1 THEN + o_fload<=o_fload-1; + END IF; + END IF; + END IF; + + -------------------------------------------------- + END CASE; + + o_read<=o_read_pre AND o_run; + + o_adrs_pre<=to_integer(o_vacpt) * o_hburst; + IF o_adrsa='1' THEN + IF HEADER THEN + IF o_fload=2 THEN + o_adrs<=to_unsigned((o_hbcpt + 1) * N_BURST,32); + o_alt<="1111"; + ELSIF o_fload=1 THEN + o_adrs<=to_unsigned((o_hburst + o_hbcpt + 1) * N_BURST,32); + o_alt<="0100"; + ELSE + o_adrs<=to_unsigned((o_adrs_pre + o_hbcpt + 1) * N_BURST,32); + o_alt<=altx(o_vacpt(1 DOWNTO 0) + 1); + END IF; + ELSE + IF o_fload=2 THEN + o_adrs<=to_unsigned(o_hbcpt * N_BURST,32); + o_alt<="1111"; + ELSIF o_fload=1 THEN + o_adrs<=to_unsigned((o_hburst + o_hbcpt) * N_BURST,32); + o_alt<="0100"; + ELSE + o_adrs<=to_unsigned((o_adrs_pre + o_hbcpt) * N_BURST,32); + o_alt<=altx(o_vacpt(1 DOWNTO 0) + 1); + END IF; + END IF; + END IF; + + ------------------------------------------------------ + -- Copy from buffered memory to pixel lines + o_sh<='0'; + IF o_copy='0' THEN + o_copyv(0)<='0'; + IF o_copylev>0 AND o_copyv(0)='0' THEN + o_copy<='1'; + END IF; + o_adturn<='0'; + + IF o_primv(0)='1' THEN + -- First memcopy of a horizontal line, carriage return ! + -- HPOS starts at 1 for the first input image pix,to keep it positive + o_hacc <=o_hacc_ini; + o_hacc_next<=o_hacc_ini + o_ihsize; + o_hacpt <=x"000"; + o_dcpt<=0; + IF o_hsize=o_ihsize THEN + o_dshi<=3; + ELSE + o_dshi<=2; + END IF; + o_acpt<=0; + o_first<='1'; + o_last<='0'; + END IF; + + IF o_bibv(0)='0' THEN + o_ad<=0; + ELSE + o_ad<=BLEN; + END IF; + ELSE + -- dshi : Force shift first two or three pixels of each line + IF o_dshi=0 THEN + dif_v:=(o_hacc_next - o_hsize + (4*OHRES)) MOD (4*OHRES); + IF dif_v>=2*OHRES THEN + o_hacc<=o_hacc_next; + o_hacc_next<=o_hacc_next + o_ihsize; + hcarry_v:=false; + ELSE + o_hacc<=dif_v; + o_hacc_next<=(dif_v + o_ihsize + (2*OHRES)) MOD (2*OHRES); + hcarry_v:=true; + END IF; + o_dcpt<=(o_dcpt+1) MOD 4096; + ELSE + o_dshi<=o_dshi-1; + hcarry_v:=false; + END IF; + IF o_dshi<=1 THEN + o_copyv(0)<='1'; + END IF; + IF hcarry_v THEN + o_hacpt<=o_hacpt+1; + o_last<=to_std_logic(o_hacpt>=o_ihsize-2); + END IF; + + IF hcarry_v OR o_dshi>0 THEN + o_sh<='1'; + o_acpt<=(o_acpt+1) MOD 16; + + -- Shift two more pixels to the right before ending line. + o_last1<=o_last; + o_last2<=o_last1; + + IF shift24_onext(o_acpt) THEN + o_ad<=(o_ad+1) MOD (2*BLEN); + END IF; + + IF o_adturn='1' AND (shift24_onext((o_acpt+1) MOD 16)) AND + (((o_ad MOD BLEN=0) AND o_lastv(0)='0') OR o_last2='1') THEN + o_copy<='0'; + lev_dec_v:='1'; + END IF; + + IF o_ad MOD BLEN=4 THEN + o_adturn<='1'; + END IF; + END IF; + END IF; + + o_acpt1<=o_acpt; o_acpt2<=o_acpt1; o_acpt3<=o_acpt2; o_acpt4<=o_acpt3; + o_ad1<=o_ad; o_ad2<=o_ad1; o_ad3<=o_ad2; + o_sh1<=o_sh; o_sh2<=o_sh1; o_sh3<=o_sh2; + o_lastt1<=o_last; o_lastt2<=o_lastt1; o_lastt3<=o_lastt2; + + ------------------------------------------------------ + IF o_sh3='1' THEN + shift_v:=shift24_opack(o_acpt4,o_shift,o_dr); + o_shift<=shift_v; + + o_hpix0<=(r=>shift_v(0 TO 7),g=>shift_v(8 TO 15),b=>shift_v(16 TO 23)); + o_hpix1<=o_hpix0; + o_hpix2<=o_hpix1; + o_hpix3<=o_hpix2; + + IF o_first='1' THEN + -- Left edge. Duplicate first pixel + o_hpix1<=(r=>shift_v(0 TO 7),g=>shift_v(8 TO 15),b=>shift_v(16 TO 23)); + o_hpix2<=(r=>shift_v(0 TO 7),g=>shift_v(8 TO 15),b=>shift_v(16 TO 23)); + o_first<='0'; + END IF; + IF o_lastt3='1' THEN + -- Right edge. Keep last pixel. + o_hpix0<=o_hpix0; + END IF; + END IF; + + ------------------------------------------------------ + -- READLEV : Number of ongoing Avalon Reads + IF lev_dec_v='1' AND lev_inc_v='0' THEN + o_readlev<=o_readlev-1; + ELSIF lev_dec_v='0' AND lev_inc_v='1' THEN + o_readlev<=o_readlev+1; + END IF; + + -- COPYLEV : Number of ongoing copies to line buffers + IF lev_dec_v='1' AND o_readack='0' THEN + o_copylev<=o_copylev-1; + ELSIF lev_dec_v='0' AND o_readack='1' THEN + o_copylev<=o_copylev+1; + END IF; + + -- FIFOs + IF lev_dec_v='1' THEN + o_primv(0 TO 1)<=o_primv(1 TO 2); -- First buffer of line + o_lastv(0 TO 1)<=o_lastv(1 TO 2); -- Last buffer of line + o_bibv (0 TO 1)<=o_bibv (1 TO 2); -- Double buffer select + END IF; + + IF lev_inc_v='1' THEN + IF o_readlev=0 OR (o_readlev=1 AND lev_dec_v='1') THEN + o_primv(0)<=prim_v; + o_lastv(0)<=last_v; + o_bibv (0)<=bib_v; + ELSIF (o_readlev=1 AND lev_dec_v='0') OR + (o_readlev=2 AND lev_dec_v='1') THEN + o_primv(1)<=prim_v; + o_lastv(1)<=last_v; + o_bibv (1)<=bib_v; + END IF; + o_primv(2)<=prim_v; + o_lastv(2)<=last_v; + o_bibv (2)<=bib_v; + END IF; + + ------------------------------------------------------ + END IF; + END PROCESS Scalaire; + + o_h_poly_a<=to_integer(o_hfrac(11 DOWNTO 12-FRAC)); + o_v_poly_a<=to_integer(o_vfrac(11 DOWNTO 12-FRAC)); + + ----------------------------------------------------------------------------- + -- Polyphase ROMs + 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); + + Polikarpov:PROCESS(poly_clk) IS + 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; + END IF; + + poly_h_wr<=poly_wr AND NOT poly_a(FRAC+2); + poly_v_wr<=poly_wr AND poly_a(FRAC+2); + 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; + END IF; + END PROCESS Polikarpov; + + ----------------------------------------------------------------------------- + -- Horizontal Scaler + HSCAL:PROCESS(o_clk) IS + VARIABLE div_v : unsigned(17 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 + dir_v:=x"000"; + div_v:=to_unsigned(o_hacc * 64,18); + + div_v:=div_v-to_unsigned(o_hsize*32,18); + dir_v(11):=NOT div_v(17); + IF div_v(17)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*16,18); + ELSE + div_v:=div_v+to_unsigned(o_hsize*16,18); + END IF; + dir_v(10):=NOT div_v(17); + o_div<=div_v; + o_dir<=dir_v; + + -- Cycle 2 + div_v:=o_div; + dir_v:=o_dir; + IF div_v(17)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*8,18); + ELSE + div_v:=div_v+to_unsigned(o_hsize*8,18); + END IF; + dir_v( 9):=NOT div_v(17); + + IF div_v(17)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*4,18); + ELSE + div_v:=div_v+to_unsigned(o_hsize*4,18); + END IF; + dir_v(8):=NOT div_v(17); + o_div2<=div_v; + o_dir2<=dir_v; + + -- Cycle 3 + div_v:=o_div2; + dir_v:=o_dir2; + IF FRAC>4 THEN + IF div_v(17)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*2,18); + ELSE + div_v:=div_v+to_unsigned(o_hsize*2,18); + END IF; + dir_v(7):=NOT div_v(17); + IF div_v(17)='0' THEN + div_v:=div_v-to_unsigned(o_hsize,18); + ELSE + div_v:=div_v+to_unsigned(o_hsize,18); + END IF; + dir_v(6):=NOT div_v(17); + END IF; + + ----------------------------------- + o_hfrac<=dir_v; + o_hfrac1<=o_hfrac; o_hfrac2<=o_hfrac1; o_hfrac3<=o_hfrac2; + + o_copyv(1 TO 7)<=o_copyv(0 TO 6); + + o_dcpt1<=o_dcpt; + IF o_dcpt1>o_hsize THEN + o_copyv(2)<='0'; + END IF; + o_dcpt2<=o_dcpt1 MOD OHRES; + o_dcpt3<=o_dcpt2; o_dcpt4<=o_dcpt3; o_dcpt5<=o_dcpt4; + o_dcpt6<=o_dcpt5; o_dcpt7<=o_dcpt6; + + o_hpixq<=(o_hpix3,o_hpix2,o_hpix1,o_hpix0); + + -- NEAREST / BILINEAR / SHARP BILINEAR --------------- + -- C1 : Pre-calc Sharp Bilinear + o_h_sbil_t<=sbil_frac1(o_hfrac); + + -- C2 : Select + o_h_frac2<=(OTHERS =>'0'); + CASE o_hmode(1 DOWNTO 0) IS + WHEN "00" => -- Nearest + IF MASK(MASK_NEAREST)='1' THEN + o_h_frac2<=near_frac(o_hfrac1); + END IF; + WHEN "01" => -- Bilinear + IF MASK(MASK_BILINEAR)='1' THEN + o_h_frac2<=bil_frac(o_hfrac1); + END IF; + WHEN "10" => -- Sharp Bilinear + IF MASK(MASK_SHARP_BILINEAR)='1' THEN + o_h_frac2<=sbil_frac2(o_hfrac1,o_h_sbil_t); + END IF; + WHEN OTHERS => + NULL; + END CASE; + + -- C3 : Opposite frac + o_h_bil_t<=bil_calc(o_h_frac2,o_hpixq); + + -- C4 : Nearest / 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 + + -- C2 : Bicubic calc T1 = X.D + C + o_h_bic_abcd1<=bic_calc0(o_hfrac1,(o_hpix3,o_hpix2,o_hpix1,o_hpix0)); + o_h_bic_tt1<=bic_calc1(o_hfrac1, + bic_calc0(o_hfrac1,(o_hpix3,o_hpix2,o_hpix1,o_hpix0))); + + -- C3 : Bicubic calc T2 = X.T1 + B + o_h_bic_abcd2<=o_h_bic_abcd1; + o_h_bic_tt2<=bic_calc2(o_hfrac2,o_h_bic_tt1,o_h_bic_abcd1); + + -- C4 : Bicubic final Y = X.T2 + A + o_h_bic_pix<=bic_calc3(o_hfrac3,o_h_bic_tt2,o_h_bic_abcd2); + + -- POLYPHASE ----------------------------------------- + -- C1 : Read memory + + -- 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_dcpt7; + o_wr<=o_alt AND (o_copyv(7) & o_copyv(7) & o_copyv(7) & o_copyv(7)); + o_ldw<=(x"00",x"00",x"00"); + + CASE o_hmode(2 DOWNTO 0) IS + WHEN "000" | "001" | "010" => -- Nearest | Bilinear | Sharp Bilinear + IF MASK(MASK_NEAREST)='1' OR + MASK(MASK_BILINEAR)='1' OR + MASK(MASK_SHARP_BILINEAR)='1' THEN + o_ldw<=o_h_bil_pix; + END IF; + WHEN "011" => -- BiCubic + IF MASK(MASK_BICUBIC)='1' THEN + o_ldw<=o_h_bic_pix; + END IF; + WHEN OTHERS => -- PolyPhase + IF MASK(MASK_POLY)='1' THEN + o_ldw<=o_h_poly_pix; + END IF; + END CASE; + ------------------------------------------------------ + END IF; + END PROCESS HSCAL; + + ----------------------------------------------------------------------------- + -- Line buffers 4 x OHRES x (R+G+B) + OLBUF:PROCESS(o_clk) IS + BEGIN + IF rising_edge(o_clk) THEN + -- WRITES + IF o_wr(0)='1' THEN o_line0(o_wadl)<=o_ldw; END IF; + IF o_wr(1)='1' THEN o_line1(o_wadl)<=o_ldw; END IF; + IF o_wr(2)='1' THEN o_line2(o_wadl)<=o_ldw; END IF; + 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); + END IF; + END PROCESS OLBUF; + + ----------------------------------------------------------------------------- + -- Output video sweep + OSWEEP:PROCESS(o_clk) IS + BEGIN + IF rising_edge(o_clk) THEN + IF o_ce='1' THEN + -- Output pixels count + IF o_hcpt+1=o_vtotal THEN + o_vcpt_pre3<=0; + ELSE + o_vcpt_pre3<=(o_vcpt_pre3+1) MOD 4096; + END IF; + o_vcpt_pre2<=o_vcpt_pre3; + o_vcpt_pre<=o_vcpt_pre2; + o_vcpt<=o_vcpt_pre; + END IF; + + o_dev(0)<=to_std_logic(o_hcpt=o_hmin AND o_hcpt<=o_hmax AND + o_vcpt>=o_vmin AND o_vcpt<=o_vmax); + o_hsv(0)<=to_std_logic(o_hcpt>=o_hsstart AND o_hcpt=o_hsstart) OR + (o_vcpt>o_vsstart AND o_vcpt + o_isyncline2<=o_isyncline; + + IF SYNCHRO THEN + -- Measure input image size + IF o_isyncline2='1' AND o_isyncline='0' THEN + o_llicpt<=0; + o_llipos<=o_llocpt; + o_llisize<=o_llicpt; + ELSE + o_llicpt<=o_llicpt+1; + END IF; + + -- Measure output image size + IF o_vss='1' AND o_vss1='0' THEN + o_llocpt<=0; + o_llup<='1'; + o_llosize<=o_llocpt; + ELSE + o_llocpt<=o_llocpt+1; + o_llup<='0'; + END IF; + + -- Period difference between input and output images + o_lldiff<=(integer(o_llosize) - integer(o_llisize)); + + o_lltune_i(14)<='0'; -- Unused + o_lltune_i(7 DOWNTO 6)<="00"; -- Unused + IF o_llup='1' THEN + o_llcpt<=0; + o_llssh<=o_llosize; + o_llos<='0'; + o_llop<='0'; + + ELSIF o_llcpt<24 THEN + -- Frequency difference + IF o_lldiff>0 AND o_llssh=o_llosize/2 AND o_llssh<(o_llosize-o_llipos) AND o_llop='0' THEN + o_lltune_i(13 DOWNTO 8)<='1' & to_unsigned(o_llcpt,5); + o_llop<='1'; + END IF; + o_llssh<=o_llssh/2; + o_llcpt<=o_llcpt+1; + + ELSIF o_llcpt=24 THEN + o_lltune_i(15)<=NOT o_lltune_i(15); + o_llcpt<=o_llcpt+1; + END IF; + END IF; + END IF; + END IF; + + END PROCESS OSWEEP; + + o_lltune<=o_lltune_i; + ----------------------------------------------------------------------------- + -- Vertical Scaler + VSCAL:PROCESS(o_clk) IS + VARIABLE pixq_v : arr_pix(0 TO 3); + BEGIN + IF rising_edge(o_clk) THEN + IF o_ce='1' THEN + -- CYCLE 1 ----------------------------------------- + -- Read mem + o_radl<=(o_hcpt-o_hmin+OHRES) MOD OHRES; + + -- CYCLE 2 ----------------------------------------- + -- Lines reordering + CASE o_vacpt(1 DOWNTO 0) IS + WHEN "10" => pixq_v:=(o_ldr0,o_ldr1,o_ldr2,o_ldr3); + WHEN "11" => pixq_v:=(o_ldr1,o_ldr2,o_ldr3,o_ldr0); + 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); + END IF; + IF to_integer(o_vacpt)>=o_ivsize+1 THEN + o_vpixq(2)<=pixq_v(1); + o_vpixq(1)<=pixq_v(1); + END IF; + + o_vpixq1<=o_vpixq; + + -- NEAREST / BILINEAR / SHARP BILINEAR ------------- + -- C3 : Pre-calc Sharp Bilinear + o_v_sbil_t<=sbil_frac1(o_vfrac); + + -- C4 : Select + o_v_frac<=(OTHERS =>'0'); + CASE o_vmode(1 DOWNTO 0) IS + WHEN "00" => -- Nearest + IF MASK(MASK_NEAREST)='1' THEN + o_v_frac<=near_frac(o_vfrac); + END IF; + WHEN "01" => -- Bilinear + IF MASK(MASK_BILINEAR)='1' THEN + o_v_frac<=bil_frac(o_vfrac); + END IF; + WHEN "10" => -- Sharp Bilinear + IF MASK(MASK_SHARP_BILINEAR)='1' THEN + o_v_frac<=sbil_frac2(o_vfrac,o_v_sbil_t); + END IF; + WHEN OTHERS => NULL; + END CASE; + + o_v_bil_t<=bil_calc(o_v_frac,o_vpixq1); + + -- C6 : 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 + 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 + 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 + 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_r<=x"00"; + o_g<=x"00"; + o_b<=x"00"; + + CASE o_vmode(2 DOWNTO 0) IS + WHEN "000" | "001" | "010" => -- Nearest | Bilinear | Sharp Bilinear + IF MASK(MASK_NEAREST)='1' OR + MASK(MASK_BILINEAR)='1' OR + MASK(MASK_SHARP_BILINEAR)='1' THEN + o_r<=o_v_bil_pix.r; + o_g<=o_v_bil_pix.g; + o_b<=o_v_bil_pix.b; + END IF; + WHEN "011" => -- BiCubic + IF MASK(MASK_BICUBIC)='1' THEN + o_r<=o_v_bic_pix.r; + o_g<=o_v_bic_pix.g; + o_b<=o_v_bic_pix.b; + END IF; + + WHEN OTHERS => -- Polyphase + IF MASK(MASK_POLY)='1' THEN + o_r<=o_v_poly_pix.r; + o_g<=o_v_poly_pix.g; + o_b<=o_v_poly_pix.b; + END IF; + END CASE; + + IF o_pev(5)='0' THEN + o_r<=x"00"; -- Border colour + o_g<=x"00"; + o_b<=x"00"; + END IF; + + IF o_mode(2 DOWNTO 0)="111" AND o_vcpt<2*8 THEN + o_r<=(OTHERS => o_debug_set); + o_g<=(OTHERS => o_debug_set); + o_b<=(OTHERS => o_debug_set); + END IF; + + ---------------------------------------------------- + END IF; + END IF; + + END PROCESS VSCAL; + + ----------------------------------------------------------------------------- + -- DEBUG + Debug:PROCESS(o_clk) IS + TYPE arr_uv8 IS ARRAY (natural RANGE <>) OF unsigned(7 DOWNTO 0); + CONSTANT CHARS : arr_uv8 :=( + x"3E", x"63", x"73", x"7B", x"6F", x"67", x"3E", x"00", -- 0 + x"0C", x"0E", x"0C", x"0C", x"0C", x"0C", x"3F", x"00", -- 1 + x"1E", x"33", x"30", x"1C", x"06", x"33", x"3F", x"00", -- 2 + x"1E", x"33", x"30", x"1C", x"30", x"33", x"1E", x"00", -- 3 + x"38", x"3C", x"36", x"33", x"7F", x"30", x"78", x"00", -- 4 + x"3F", x"03", x"1F", x"30", x"30", x"33", x"1E", x"00", -- 5 + x"1C", x"06", x"03", x"1F", x"33", x"33", x"1E", x"00", -- 6 + x"3F", x"33", x"30", x"18", x"0C", x"0C", x"0C", x"00", -- 7 + x"1E", x"33", x"33", x"1E", x"33", x"33", x"1E", x"00", -- 8 + x"1E", x"33", x"33", x"3E", x"30", x"18", x"0E", x"00", -- 9 + x"0C", x"1E", x"33", x"33", x"3F", x"33", x"33", x"00", -- A + x"3F", x"66", x"66", x"3E", x"66", x"66", x"3F", x"00", -- B + x"3C", x"66", x"03", x"03", x"03", x"66", x"3C", x"00", -- C + x"1F", x"36", x"66", x"66", x"66", x"36", x"1F", x"00", -- D + x"7F", x"46", x"16", x"1E", x"16", x"46", x"7F", x"00", -- E + x"7F", x"46", x"16", x"1E", x"16", x"06", x"0F", x"00", -- F + x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", --' ' 10 + x"00", x"00", x"3F", x"00", x"00", x"3F", x"00", x"00", -- = 11 + x"00", x"0C", x"0C", x"3F", x"0C", x"0C", x"00", x"00", -- + 12 + x"00", x"00", x"00", x"3F", x"00", x"00", x"00", x"00", -- - 13 + x"18", x"0C", x"06", x"03", x"06", x"0C", x"18", x"00", -- < 14 + x"06", x"0C", x"18", x"30", x"18", x"0C", x"06", x"00", -- > 15 + x"08", x"1C", x"36", x"63", x"41", x"00", x"00", x"00", -- ^ 16 + x"08", x"1C", x"36", x"63", x"41", x"00", x"00", x"00", -- v 17 + x"18", x"0C", x"06", x"06", x"06", x"0C", x"18", x"00", -- ( 18 + x"06", x"0C", x"18", x"18", x"18", x"0C", x"06", x"00", -- ) 19 + x"00", x"0C", x"0C", x"00", x"00", x"0C", x"0C", x"00", -- : 1A + x"00", x"00", x"00", x"00", x"00", x"0C", x"0C", x"00", -- . 1B + x"00", x"00", x"00", x"00", x"00", x"0C", x"0C", x"06", -- , 1C + x"1E", x"33", x"30", x"18", x"0C", x"00", x"0C", x"00", -- ? 1D + x"18", x"18", x"18", x"00", x"18", x"18", x"18", x"00", -- | 1E + x"36", x"36", x"7F", x"36", x"7F", x"36", x"36", x"00"); -- # 1F + + VARIABLE vin_v : unsigned(0 TO 32*5-1); + BEGIN + IF rising_edge(o_clk) THEN + IF o_ce='1' THEN + o_debug_hcpt2<=o_hcpt; + o_debug_hcpt3<=o_debug_hcpt2; + o_debug_hcpt4<=o_debug_hcpt3; + o_debug_hcpt5<=o_debug_hcpt4; + o_debug_hcpt6<=o_debug_hcpt5; + IF (o_vcpt/8) MOD 2=0 THEN + vin_v:=o_debug_vin0; + ELSE + vin_v:=o_debug_vin1; + END IF; + o_debug_hchar<=((o_debug_hcpt2/8)*5) MOD 256; + IF o_debug_hcpt3<32 * 8 AND o_vcpt<2 * 8 THEN + o_debug_char<=vin_v(o_debug_hchar TO o_debug_hchar+4); + ELSE + o_debug_char<="10000"; -- " " : Blank character + END IF; + + o_debug_col<=CHARS(to_integer(o_debug_char)*8+(o_vcpt MOD 8)); + + IF o_debug_col(o_debug_hcpt6 MOD 8)='1' THEN + o_debug_set<='1'; + ELSE + o_debug_set<='0'; + END IF; + END IF; + END IF; + END PROCESS Debug; + + ---------------------------------------------------------- + o_debug_vin0<= + CN(to_unsigned(i_himax ,12)) & -- 3 + CC(' ') & + CN(to_unsigned(i_hsstart,12)) & -- 3 + CC(' ') & + CN(to_unsigned(i_hsend ,12)) & -- 3 + CC(' ') & + CN(to_unsigned(i_htotal ,12)) & -- 3 + "1001" & NOT i_inter & + CN(to_unsigned(i_vimax ,12)) & -- 3 + CC(' ') & + CN(to_unsigned(i_vsstart,12)) & -- 3 + CC(' ') & + CN(to_unsigned(i_vsend ,12)) & -- 3 + CC(' ') & + CN(to_unsigned(i_vtotal ,12)) & -- 3 + CC(' '); + + o_debug_vin1<= + "0000" & i_inter & -- 1 + CC(' ') & -- 1 + CN(to_unsigned(o_lldiff,24)) & -- 6 + CC(' ') & -- 1 + CN(to_unsigned(o_llipos,24)) & -- 6 + CC(' ') & -- 1 + "0000" & o_lltune_i(15) & -- 1 + CC(' ') & -- 1 + "00" & o_lltune_i(14 DOWNTO 12) & -- 1 + '0' & o_lltune_i(11 DOWNTO 8) & -- 1 + '0' & o_lltune_i(7 DOWNTO 4) & -- 1 + '0' & o_lltune_i(3 DOWNTO 0) & -- 1 + CS(" "); + ---------------------------------------------------------------------------- +END ARCHITECTURE rtl; + diff --git a/sys/coeff.mif b/sys/coeff.mif new file mode 100644 index 0000000..aca2c7a --- /dev/null +++ b/sys/coeff.mif @@ -0,0 +1,71 @@ +DEPTH = 256; +WIDTH = 9; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +000: 1E8 0B0 1E8 000; +004: 1EC 0AE 1E6 000; +008: 1F0 0A9 1E6 001; +00C: 1F5 0A0 1E9 002; +010: 1FA 093 1F0 003; +014: 1FF 081 1FC 004; +018: 002 06D 00B 006; +01C: 005 054 020 007; +020: 006 03A 03A 006; +024: 006 016 060 004; +028: 005 003 077 001; +02C: 004 1F4 08C 1FC; +030: 002 1EC 09A 1F8; +034: 001 1E7 0A5 1F3; +038: 000 1E6 0AC 1EE; +03C: 000 1E7 0AF 1EA; +040: 000 080 000 000; +044: 1FC 07E 006 000; +048: 1F8 07C 00D 1FF; +04C: 1F6 077 014 1FF; +050: 1F5 06F 01E 1FE; +054: 1F5 067 028 1FC; +058: 1F6 05D 032 1FB; +05C: 1F7 052 03D 1FA; +060: 1F8 048 048 1F8; +064: 1FA 038 058 1F6; +068: 1FC 02D 062 1F5; +06C: 1FD 023 06B 1F5; +070: 1FE 019 073 1F6; +074: 1FF 011 079 1F7; +078: 000 009 07D 1FA; +07C: 000 003 07F 1FE; + +080: 000 080 000 000; +084: 000 080 000 000; +088: 000 080 000 000; +08C: 000 080 000 000; +090: 000 080 000 000; +094: 000 080 000 000; +098: 000 080 000 000; +09C: 000 080 000 000; +0A0: 000 080 000 000; +0A4: 000 080 000 000; +0A8: 000 080 000 000; +0AC: 000 080 000 000; +0B0: 000 080 000 000; +0B4: 000 080 000 000; +0B8: 000 080 000 000; +0BC: 000 080 000 000; +0C0: 000 080 000 000; +0C4: 000 080 000 000; +0C8: 000 080 000 000; +0CC: 000 080 000 000; +0D0: 000 080 000 000; +0D4: 000 080 000 000; +0D8: 000 080 000 000; +0DC: 000 080 000 000; +0E0: 000 080 000 000; +0E4: 000 080 000 000; +0E8: 000 080 000 000; +0EC: 000 080 000 000; +0F0: 000 080 000 000; +0F4: 000 080 000 000; +0F8: 000 080 000 000; +0FC: 000 080 000 000; +END; diff --git a/sys/hdmi_config.sv b/sys/hdmi_config.sv index 0321792..476d72d 100644 --- a/sys/hdmi_config.sv +++ b/sys/hdmi_config.sv @@ -142,9 +142,9 @@ wire [15:0] init_data[58] = 16'hAA00, // ADI required Write. 16'hAB40, // ADI required Write. - {8'hAF, 6'b0001_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. + {8'hAF, 6'b0000_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. // [6:5] must be b00! - // [4]=1 Current frame IS HDCP encrypted!??? (HDCP disabled anyway?) + // [4]=0 Current frame is unencrypted // [3:2] must be b01! // [1]=1 HDMI Mode. // [0] must be b0! diff --git a/sys/hdmi_lite.sv b/sys/hdmi_lite.sv deleted file mode 100644 index 96eb441..0000000 --- a/sys/hdmi_lite.sv +++ /dev/null @@ -1,395 +0,0 @@ -//============================================================================ -// -// HDMI Lite output module -// Copyright (C) 2017 Sorgelig -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -//============================================================================ - - -module hdmi_lite -( - input reset, - - input clk_video, - input ce_pixel, - input video_vs, - input video_de, - input [23:0] video_d, - - input clk_hdmi, - input hdmi_hde, - input hdmi_vde, - output reg hdmi_de, - output [23:0] hdmi_d, - - input [11:0] screen_w, - input [11:0] screen_h, - input quadbuf, - - // 0-3 => scale 1-4 - input [1:0] scale_x, - input [1:0] scale_y, - input scale_auto, - - input clk_vbuf, - output [27:0] vbuf_address, - input [127:0] vbuf_readdata, - output [127:0] vbuf_writedata, - output [7:0] vbuf_burstcount, - output [15:0] vbuf_byteenable, - input vbuf_waitrequest, - input vbuf_readdatavalid, - output reg vbuf_read, - output reg vbuf_write -); - -localparam [7:0] burstsz = 64; - -reg [1:0] nbuf = 0; -wire [27:0] read_buf = {4'd2, 3'b000, (quadbuf ? nbuf-2'd1 : 2'b00), 19'd0}; -wire [27:0] write_buf = {4'd2, 3'b000, (quadbuf ? nbuf+2'd1 : 2'b00), 19'd0}; - -assign vbuf_address = vbuf_write ? vbuf_waddress : vbuf_raddress; -assign vbuf_burstcount = vbuf_write ? vbuf_wburstcount : vbuf_rburstcount; - -wire [95:0] hf_out; -wire [7:0] hf_usedw; -reg hf_reset = 0; - -vbuf_fifo out_fifo -( - .aclr(hf_reset), - - .wrclk(clk_vbuf), - .wrreq(vbuf_readdatavalid), - .data({vbuf_readdata[96+:24],vbuf_readdata[64+:24],vbuf_readdata[32+:24],vbuf_readdata[0+:24]}), - .wrusedw(hf_usedw), - - .rdclk(~clk_hdmi), - .rdreq(hf_rdreq), - .q(hf_out) -); - -reg [11:0] rd_stride; -wire [7:0] rd_burst = (burstsz < rd_stride) ? burstsz : rd_stride[7:0]; - -reg [27:0] vbuf_raddress; -reg [7:0] vbuf_rburstcount; -always @(posedge clk_vbuf) begin - reg [18:0] rdcnt; - reg [7:0] bcnt; - reg vde1, vde2; - reg [1:0] mcnt; - reg [1:0] my; - reg [18:0] fsz; - reg [11:0] strd; - - vde1 <= hdmi_vde; - vde2 <= vde1; - - if(vbuf_readdatavalid) begin - rdcnt <= rdcnt + 1'd1; - if(bcnt) bcnt <= bcnt - 1'd1; - vbuf_raddress <= vbuf_raddress + 1'd1; - end - - if(!bcnt && reading) reading <= 0; - - vbuf_read <= 0; - if(~vbuf_waitrequest) begin - if(!hf_reset && rdcnt=off_x) && (x<(vh_width+off_x)) && (y>=off_y) && (y<(vh_height+off_y)) && !hload && !pcnt; -wire de_in = hdmi_hde & hdmi_vde; - -always @(posedge clk_hdmi) begin - reg [71:0] px_out; - reg [1:0] mx; - reg vde; - - vde <= hdmi_vde; - - if(vde & ~hdmi_vde) begin - off_x <= (screen_w>v_width) ? (screen_w - v_width)>>1 : 12'd0; - off_y <= (screen_h>v_height) ? (screen_h - v_height)>>1 : 12'd0; - vh_height <= v_height; - vh_width <= v_width; - mx <= mult_x; - end - - pcnt <= pcnt + 1'd1; - if(pcnt == mx) begin - pcnt <= 0; - hload <= hload + 1'd1; - end - - if(~de_in || x (screen_h/2)) ? 2'b00 : (video_y > (screen_h/3)) ? 2'b01 : (video_y > (screen_h/4)) ? 2'b10 : 2'b11; -wire [1:0] tm_x = (l1_width > (screen_w/2)) ? 2'b00 : (l1_width > (screen_w/3)) ? 2'b01 : (l1_width > (screen_w/4)) ? 2'b10 : 2'b11; -wire [1:0] tm_xy = (tm_x < tm_y) ? tm_x : tm_y; -wire [1:0] tmf_y = scale_auto ? tm_xy : scale_y; -wire [1:0] tmf_x = scale_auto ? tm_xy : scale_x; -wire [11:0] t_height = video_y + (tmf_y[0] ? video_y : 12'd0) + (tmf_y[1] ? video_y<<1 : 12'd0); -wire [11:0] t_width = l1_width + (tmf_x[0] ? l1_width : 12'd0) + (tmf_x[1] ? l1_width<<1 : 12'd0); -wire [23:0] t_fsz = l1_stride * t_height; - -reg [11:0] l1_width; -reg [11:0] l1_stride; -always @(posedge clk_video) begin - reg [7:0] loaded = 0; - reg [11:0] strd = 0; - reg old_de = 0; - reg old_vs = 0; - - old_vs <= video_vs; - if(~old_vs & video_vs) begin - cur_addr<= write_buf; - video_x <= 0; - video_y <= 0; - loaded <= 0; - strd <= 0; - nbuf <= nbuf + 1'd1; - - stride <= l1_stride; - framesz <= t_fsz[18:0]; - v_height<= t_height; - v_width <= t_width; - mult_x <= tmf_x; - mult_y <= tmf_y; - end - - if(pix_wr) begin - case(video_x[1:0]) - 0: pix_acc <= video_d; // zeroes upper bits too - 1: pix_acc[47:24] <= video_d; - 2: pix_acc[71:48] <= video_d; - 3: loaded <= loaded + 1'd1; - endcase - if(video_x= burstsz) || (old_de & ~video_de)) begin - if(loaded + infifo_tail) begin - flush_size <= loaded + infifo_tail; - flush_addr <= cur_addr; - flush_req <= ~flush_req; - loaded <= 0; - strd <= strd + loaded; - end - - cur_addr <= cur_addr + loaded + infifo_tail; - if(~video_de) begin - if(video_y>1) + OSD_X_OFFSET - 2'd2); + if(h_cnt > {dsp_width, 2'b00}) begin v_cnt <= 0; - dsp_height <= v_cnt; - if(osd_enable) begin - if(v_cnt<320) begin - multiscan <= 0; - fheight <= hrheight; - finfoy <= infoy; - end - else if(v_cnt<640) begin - multiscan <= 1; - fheight <= hrheight << 1; - finfoy <= infoy << 1; - end - else if(v_cnt<960) begin - multiscan <= 2; - fheight <= hrheight + (hrheight<<1); - finfoy <= infoy + (infoy << 1); - end - else begin - multiscan <= 3; - fheight <= hrheight << 2; - finfoy <= infoy << 2; - end + osd_en <= (osd_en << 1) | osd_enable; + if(~osd_enable) osd_en <= 0; + + if(v_cnt<320) begin + multiscan <= 0; + v_osd_start <= info ? infoy : (((v_cnt-hrheight)>>1) + OSD_Y_OFFSET); + end + else if(v_cnt<640) begin + multiscan <= 1; + v_osd_start <= info ? (infoy<<1) : (((v_cnt-(hrheight<<1))>>1) + OSD_Y_OFFSET); + end + else if(v_cnt<960) begin + multiscan <= 2; + v_osd_start <= info ? (infoy + (infoy << 1)) : (((v_cnt-(hrheight + (hrheight<<1)))>>1) + OSD_Y_OFFSET); end else begin - fheight <= 0; + multiscan <= 3; + v_osd_start <= info ? (infoy<<2) : (((v_cnt-(hrheight<<2))>>1) + OSD_Y_OFFSET); end end - h_cnt <= 0; - + osd_div <= osd_div + 1'd1; if(osd_div == multiscan) begin osd_div <= 0; - osd_vcnt <= osd_vcnt + 1'd1; + if(~&osd_vcnt) osd_vcnt <= osd_vcnt + 1'd1; end if(v_osd_start == (v_cnt+1'b1)) {osd_div, osd_vcnt} <= 0; end - - osd_byte <= osd_buffer[{osd_vcnt[6:3], osd_hcnt[7:0]}]; + + osd_byte <= osd_buffer[{osd_vcnt[6:3], osd_hcnt[7:0]}]; + osd_pixel <= osd_byte[osd_vcnt[2:0]]; + osd_de[2:1] <= osd_de[1:0]; end end -// area in which OSD is being displayed -wire [21:0] h_osd_start = info ? infox : ((dsp_width - OSD_WIDTH)>>1) + OSD_X_OFFSET; -wire [21:0] h_osd_end = info ? (h_osd_start + infow) : (h_osd_start + OSD_WIDTH); -wire [21:0] v_osd_start = info ? finfoy : ((dsp_height- fheight)>>1) + OSD_Y_OFFSET; -wire [21:0] v_osd_end = v_osd_start + fheight; - -wire [21:0] osd_hcnt = h_cnt[21:0] - h_osd_start + 1'd1; - -wire osd_de = osd_enable && fheight && - (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) && - (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); - -wire osd_pixel = osd_byte[osd_vcnt[2:0]]; - reg [23:0] rdout; assign dout = rdout; - + always @(posedge clk_video) begin - rdout <= !osd_de ? din : {{osd_pixel, osd_pixel, OSD_COLOR[2], din[23:19]}, - {osd_pixel, osd_pixel, OSD_COLOR[1], din[15:11]}, - {osd_pixel, osd_pixel, OSD_COLOR[0], din[7:3]}}; + rdout <= ~osd_de[2] ? din : {{osd_pixel, osd_pixel, OSD_COLOR[2], din[23:19]}, + {osd_pixel, osd_pixel, OSD_COLOR[1], din[15:11]}, + {osd_pixel, osd_pixel, OSD_COLOR[0], din[7:3]}}; de_out <= de_in; end diff --git a/sys/pattern_vg.v b/sys/pattern_vg.v deleted file mode 100644 index 6379278..0000000 --- a/sys/pattern_vg.v +++ /dev/null @@ -1,120 +0,0 @@ -module pattern_vg -#( - parameter B=8, // number of bits per channel - X_BITS=13, - Y_BITS=13, - FRACTIONAL_BITS = 12 -) - -( - input reset, clk_in, - input wire [X_BITS-1:0] x, - input wire [Y_BITS-1:0] y, - input wire vn_in, hn_in, dn_in, - input wire [B-1:0] r_in, g_in, b_in, - output reg vn_out, hn_out, den_out, - output reg [B-1:0] r_out, g_out, b_out, - input wire [X_BITS-1:0] total_active_pix, - input wire [Y_BITS-1:0] total_active_lines, - input wire [7:0] pattern, - input wire [B+FRACTIONAL_BITS-1:0] ramp_step -); - -reg [B+FRACTIONAL_BITS-1:0] ramp_values; // 12-bit fractional end for ramp values - - -//wire bar_0 = y<90; -wire bar_1 = y>=90 & y<180; -wire bar_2 = y>=180 & y<270; -wire bar_3 = y>=270 & y<360; -wire bar_4 = y>=360 & y<450; -wire bar_5 = y>=450 & y<540; -wire bar_6 = y>=540 & y<630; -wire bar_7 = y>=630 & y<720; - - -wire red_enable = bar_1 | bar_3 | bar_5 | bar_7; -wire green_enable = bar_2 | bar_3 | bar_6 | bar_7; -wire blue_enable = bar_4 | bar_5 | bar_6 | bar_7; - -always @(posedge clk_in) - begin - vn_out <= vn_in; - hn_out <= hn_in; - den_out <= dn_in; - if (reset) - ramp_values <= 0; - else if (pattern == 8'b0) // no pattern - begin - r_out <= r_in; - g_out <= g_in; - b_out <= b_in; - end - else if (pattern == 8'b1) // border - begin - if (dn_in && ((y == 12'b0) || (x == 12'b0) || (x == total_active_pix - 1) || (y == total_active_lines - 1))) - begin - r_out <= 8'hFF; - g_out <= 8'hFF; - b_out <= 8'hFF; - end - else // Double-border (OzOnE)... - if (dn_in && ((y == 12'b0+20) || (x == 12'b0+20) || (x == total_active_pix - 1 - 20) || (y == total_active_lines - 1 - 20))) - begin - r_out <= 8'hD0; - g_out <= 8'hB0; - b_out <= 8'hB0; - end - else - begin - r_out <= r_in; - g_out <= g_in; - b_out <= b_in; - end - end - else if (pattern == 8'd2) // moireX - begin - if ((dn_in) && x[0] == 1'b1) - begin - r_out <= 8'hFF; - g_out <= 8'hFF; - b_out <= 8'hFF; - end - else - begin - r_out <= 8'b0; - g_out <= 8'b0; - b_out <= 8'b0; - end - end - else if (pattern == 8'd3) // moireY - begin - if ((dn_in) && y[0] == 1'b1) - begin - r_out <= 8'hFF; - g_out <= 8'hFF; - b_out <= 8'hFF; - end - else - begin - r_out <= 8'b0; - g_out <= 8'b0; - b_out <= 8'b0; - end - end - else if (pattern == 8'd4) // Simple RAMP - begin - r_out <= (red_enable) ? ramp_values[B+FRACTIONAL_BITS-1:FRACTIONAL_BITS] : 8'h00; - g_out <= (green_enable) ? ramp_values[B+FRACTIONAL_BITS-1:FRACTIONAL_BITS] : 8'h00; - b_out <= (blue_enable) ? ramp_values[B+FRACTIONAL_BITS-1:FRACTIONAL_BITS] : 8'h00; - - if ((x == total_active_pix - 1) && (dn_in)) - ramp_values <= 0; - else if ((x == 0) && (dn_in)) - ramp_values <= ramp_step; - else if (dn_in) - ramp_values <= ramp_values + ramp_step; - end -end - -endmodule diff --git a/sys/pll.qip b/sys/pll.qip index 715f490..16a3fb5 100644 --- a/sys/pll.qip +++ b/sys/pll.qip @@ -35,8 +35,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=::Mg==::TnVtYmVyIE9mIENsb2Nrcw==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::Mg==::bnVtYmVyX29mX2Nsb2Nrcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::Mw==::TnVtYmVyIE9mIENsb2Nrcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::Mw==::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==" @@ -65,11 +65,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 "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::MTQuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::NTYuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MTEy::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MTAw::QWN0dWFsIERpdmlkZSBGYWN0b3I=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" @@ -262,7 +262,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 "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::MTEyLjAwMDAwMCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::LTQzNTIgcHM=::cGhhc2Vfc2hpZnQx" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::NTYuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::MCBwcw==::cGhhc2Vfc2hpZnQy" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" @@ -317,8 +317,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 "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU=" set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU=" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" -set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NTYsNTYsMywyLGZhbHNlLGZhbHNlLGZhbHNlLHRydWUsNSw1LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDUsNSw2LDEscGhfbXV4X2NsayxmYWxzZSxmYWxzZSwxLDIwLDEwMDAwLDExMjAuMCBNSHosMSxub25lLGdsYixtX2NudCxwaF9tdXhfY2xrLHRydWU=::UGFyYW1ldGVyIFZhbHVlcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NTYsNTYsMywyLGZhbHNlLGZhbHNlLGZhbHNlLHRydWUsNSw1LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDUsNSw2LDEscGhfbXV4X2NsayxmYWxzZSxmYWxzZSwxMCwxMCwxLDAscGhfbXV4X2NsayxmYWxzZSxmYWxzZSwxLDIwLDEwMDAwLDExMjAuMCBNSHosMSxub25lLGdsYixtX2NudCxwaF9tdXhfY2xrLHRydWU=::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/sys/pll.v b/sys/pll.v index 240799d..bf5d0c6 100644 --- a/sys/pll.v +++ b/sys/pll.v @@ -2,7 +2,7 @@ // GENERATION: XML // pll.v -// Generated using ACDS version 17.0 598 +// Generated using ACDS version 17.0 602 `timescale 1 ps / 1 ps module pll ( @@ -10,6 +10,7 @@ module pll ( input wire rst, // reset.reset output wire outclk_0, // outclk0.clk output wire outclk_1, // outclk1.clk + output wire outclk_2, // outclk2.clk output wire locked // locked.export ); @@ -18,6 +19,7 @@ module pll ( .rst (rst), // reset.reset .outclk_0 (outclk_0), // outclk0.clk .outclk_1 (outclk_1), // outclk1.clk + .outclk_2 (outclk_2), // outclk2.clk .locked (locked) // locked.export ); @@ -28,7 +30,7 @@ endmodule // ************************************************************ // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! // ************************************************************ -// Copyright (C) 1991-2017 Altera Corporation +// Copyright (C) 1991-2018 Altera Corporation // Any megafunction design, and related net list (encrypted or decrypted), // support information, device programming or simulation file, and any other // associated documentation or information provided by Altera or a partner @@ -63,7 +65,7 @@ endmodule // Retrieval info: // Retrieval info: // Retrieval info: -// Retrieval info: +// Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: @@ -86,7 +88,7 @@ endmodule // Retrieval info: // Retrieval info: // Retrieval info: -// Retrieval info: +// Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: diff --git a/sys/pll/pll_0002.v b/sys/pll/pll_0002.v index 1a410c6..015b8e3 100644 --- a/sys/pll/pll_0002.v +++ b/sys/pll/pll_0002.v @@ -13,6 +13,9 @@ module pll_0002( // interface 'outclk1' output wire outclk_1, + // interface 'outclk2' + output wire outclk_2, + // interface 'locked' output wire locked ); @@ -21,14 +24,14 @@ module pll_0002( .fractional_vco_multiplier("false"), .reference_clock_frequency("50.0 MHz"), .operation_mode("direct"), - .number_of_clocks(2), + .number_of_clocks(3), .output_clock_frequency0("112.000000 MHz"), .phase_shift0("0 ps"), .duty_cycle0(50), .output_clock_frequency1("112.000000 MHz"), .phase_shift1("-4352 ps"), .duty_cycle1(50), - .output_clock_frequency2("0 MHz"), + .output_clock_frequency2("56.000000 MHz"), .phase_shift2("0 ps"), .duty_cycle2(50), .output_clock_frequency3("0 MHz"), @@ -80,7 +83,7 @@ module pll_0002( .pll_subtype("General") ) altera_pll_i ( .rst (rst), - .outclk ({outclk_1, outclk_0}), + .outclk ({outclk_2, outclk_1, outclk_0}), .locked (locked), .fboutclk ( ), .fbclk (1'b0), diff --git a/sys/reset_source.v b/sys/reset_source.v new file mode 100644 index 0000000..1b81394 --- /dev/null +++ b/sys/reset_source.v @@ -0,0 +1,50 @@ +// reset_source.v + +// This file was auto-generated as a prototype implementation of a module +// created in component editor. It ties off all outputs to ground and +// ignores all inputs. It needs to be edited to make it do something +// useful. +// +// This file will not be automatically regenerated. You should check it in +// to your version control system if you want to keep it. + +`timescale 1 ps / 1 ps +module reset_source +( + input wire clk, // clock.clk + input wire reset_hps, // reset_hps.reset + output wire reset_sys, // reset_sys.reset + output wire reset_cold, // reset_cold.reset + input wire cold_req, // reset_ctl.cold_req + output wire reset, // .reset + input wire reset_req, // .reset_req + input wire reset_vip, // .reset_vip + input wire warm_req, // .warm_req + output wire reset_warm // reset_warm.reset +); + +assign reset_cold = cold_req; +assign reset_warm = warm_req; + +wire reset_m = sys_reset | reset_hps | reset_req; +assign reset = reset_m; +assign reset_sys = reset_m | reset_vip; + +reg sys_reset = 1; +always @(posedge clk) begin + integer timeout = 0; + reg reset_lock = 0; + + reset_lock <= reset_lock | cold_req; + + if(timeout < 2000000) begin + sys_reset <= 1; + timeout <= timeout + 1; + reset_lock <= 0; + end + else begin + sys_reset <= reset_lock; + end +end + +endmodule diff --git a/sys/scanlines.v b/sys/scanlines.v new file mode 100644 index 0000000..96aa6e3 --- /dev/null +++ b/sys/scanlines.v @@ -0,0 +1,52 @@ +module scanlines #(parameter v2=0) +( + input clk, + + input [1:0] scanlines, + input [23:0] din, + output reg [23:0] dout, + input hs,vs +); + +reg [1:0] scanline; +always @(posedge clk) begin + reg old_hs, old_vs; + + old_hs <= hs; + old_vs <= vs; + + if(old_hs && ~hs) begin + if(v2) begin + scanline <= scanline + 1'd1; + if (scanline == scanlines) scanline <= 0; + end + else scanline <= scanline ^ scanlines; + end + if(old_vs && ~vs) scanline <= 0; +end + +wire [7:0] r,g,b; +assign {r,g,b} = din; + +always @(*) begin + case(scanline) + 1: // reduce 25% = 1/2 + 1/4 + dout = {{1'b0, r[7:1]} + {2'b00, r[7:2]}, + {1'b0, g[7:1]} + {2'b00, g[7:2]}, + {1'b0, b[7:1]} + {2'b00, b[7:2]}}; + + 2: // reduce 50% = 1/2 + dout = {{1'b0, r[7:1]}, + {1'b0, g[7:1]}, + {1'b0, b[7:1]}}; + + 3: // reduce 75% = 1/4 + dout = {{2'b00, r[7:2]}, + {2'b00, g[7:2]}, + {2'b00, b[7:2]}}; + + default: dout = {r,g,b}; + endcase +end + +endmodule diff --git a/sys/sync_vg.v b/sys/sync_vg.v deleted file mode 100644 index 54fc614..0000000 --- a/sys/sync_vg.v +++ /dev/null @@ -1,78 +0,0 @@ -module sync_vg -#( - parameter X_BITS=12, Y_BITS=12 -) -( - input wire clk, - input wire reset, - - input wire [Y_BITS-1:0] v_total, - input wire [Y_BITS-1:0] v_fp, - input wire [Y_BITS-1:0] v_bp, - input wire [Y_BITS-1:0] v_sync, - input wire [X_BITS-1:0] h_total, - input wire [X_BITS-1:0] h_fp, - input wire [X_BITS-1:0] h_bp, - input wire [X_BITS-1:0] h_sync, - input wire [X_BITS-1:0] hv_offset, - - output reg vs_out, - output reg hs_out, - output reg hde_out, - output reg vde_out, - output reg [Y_BITS-1:0] v_count_out, - output reg [X_BITS-1:0] h_count_out, - output reg [X_BITS-1:0] x_out, - output reg [Y_BITS-1:0] y_out -); - -reg [X_BITS-1:0] h_count; -reg [Y_BITS-1:0] v_count; - -/* horizontal counter */ -always @(posedge clk) - if (reset) - h_count <= 0; - else - if (h_count < h_total - 1) - h_count <= h_count + 1'd1; - else - h_count <= 0; - -/* vertical counter */ -always @(posedge clk) - if (reset) - v_count <= 0; - else - if (h_count == h_total - 1) - begin - if (v_count == v_total - 1) - v_count <= 0; - else - v_count <= v_count + 1'd1; - end - -always @(posedge clk) - if (reset) - { vs_out, hs_out, hde_out, vde_out } <= 0; - else begin - hs_out <= ((h_count < h_sync)); - - hde_out <= (h_count >= h_sync + h_bp) && (h_count <= h_total - h_fp - 1); - vde_out <= (v_count >= v_sync + v_bp) && (v_count <= v_total - v_fp - 1); - - if ((v_count == 0) && (h_count == hv_offset)) - vs_out <= 1'b1; - else if ((v_count == v_sync) && (h_count == hv_offset)) - vs_out <= 1'b0; - - /* H_COUNT_OUT and V_COUNT_OUT */ - h_count_out <= h_count; - v_count_out <= v_count; - - /* X and Y coords for a backend pattern generator */ - x_out <= h_count - (h_sync + h_bp); - y_out <= v_count - (v_sync + v_bp); - end - -endmodule diff --git a/sys/sys.qip b/sys/sys.qip index 3e5268a..3dd4831 100644 --- a/sys/sys.qip +++ b/sys/sys.qip @@ -1,25 +1,25 @@ -set_global_assignment -name VERILOG_FILE sys/sys_top.v -set_global_assignment -name SDC_FILE sys/sys_top.sdc -set_global_assignment -name QIP_FILE sys/pll.qip -set_global_assignment -name QIP_FILE sys/pll_hdmi.qip -set_global_assignment -name QIP_FILE sys/pll_hdmi_cfg.qip -set_global_assignment -name SYSTEMVERILOG_FILE sys/hdmi_lite.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/hq2x.sv -set_global_assignment -name VERILOG_FILE sys/scandoubler.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/video_cleaner.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/video_mixer.sv -set_global_assignment -name VERILOG_FILE sys/osd.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/vga_out.sv -set_global_assignment -name VERILOG_FILE sys/sync_vg.v -set_global_assignment -name VERILOG_FILE sys/pattern_vg.v -set_global_assignment -name VERILOG_FILE sys/i2c.v -set_global_assignment -name VERILOG_FILE sys/i2s.v -set_global_assignment -name VERILOG_FILE sys/spdif.v -set_global_assignment -name VERILOG_FILE sys/sigma_delta_dac.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/lpf48k.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/hdmi_config.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/sysmem.sv -set_global_assignment -name VERILOG_FILE sys/ip/reset_source.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/vip_config.sv -set_global_assignment -name VERILOG_FILE sys/sd_card.v -set_global_assignment -name VERILOG_FILE sys/hps_io.v +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ] +set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.qip ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.qip ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) lpf48k.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) reset_source.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vip_config.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ] +set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sysmem_HPS_fpga_interfaces -to peripheral_uart1 diff --git a/sys/sys_q13.qip b/sys/sys_q13.qip index cf39a80..c765279 100644 --- a/sys/sys_q13.qip +++ b/sys/sys_q13.qip @@ -1,29 +1,29 @@ -set_global_assignment -name VERILOG_FILE sys/sys_top.v -set_global_assignment -name SDC_FILE sys/sys_top.sdc -set_global_assignment -name VERILOG_FILE sys/pll.v -set_global_assignment -name VERILOG_FILE sys/pll/pll_0002.v -set_global_assignment -name QIP_FILE sys/pll/pll_0002.qip -set_global_assignment -name QIP_FILE sys/pll_hdmi_q13.qip -set_global_assignment -name VERILOG_FILE sys/pll_hdmi_cfg.v -set_global_assignment -name VERILOG_FILE sys/pll_hdmi_cfg/altera_pll_reconfig_core.v -set_global_assignment -name VERILOG_FILE sys/pll_hdmi_cfg/altera_pll_reconfig_top.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/hdmi_lite.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/hq2x.sv -set_global_assignment -name VERILOG_FILE sys/scandoubler.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/video_cleaner.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/video_mixer.sv -set_global_assignment -name VERILOG_FILE sys/osd.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/vga_out.sv -set_global_assignment -name VERILOG_FILE sys/sync_vg.v -set_global_assignment -name VERILOG_FILE sys/pattern_vg.v -set_global_assignment -name VERILOG_FILE sys/i2c.v -set_global_assignment -name VERILOG_FILE sys/i2s.v -set_global_assignment -name VERILOG_FILE sys/spdif.v -set_global_assignment -name VERILOG_FILE sys/sigma_delta_dac.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/lpf48k.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/hdmi_config.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/sysmem.sv -set_global_assignment -name VERILOG_FILE sys/ip/reset_source.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/vip_config.sv -set_global_assignment -name VERILOG_FILE sys/sd_card.v -set_global_assignment -name VERILOG_FILE sys/hps_io.v +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ] +set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll/pll_0002.v ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll/pll_0002.qip ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_q13.qip ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_core.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_top.v ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) lpf48k.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) reset_source.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vip_config.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ] +set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sysmem_HPS_fpga_interfaces -to peripheral_uart1 diff --git a/sys/sys_top.v b/sys/sys_top.v index 2af99b1..215c71e 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -189,16 +189,14 @@ cyclonev_hps_interface_mpu_general_purpose h2f_gp reg [15:0] cfg; -reg cfg_got = 0; -reg cfg_set = 0; +reg cfg_got = 0; +reg cfg_set = 0; //wire [2:0] hdmi_res = cfg[10:8]; -wire dvi_mode = cfg[7]; -wire audio_96k = cfg[6]; -wire ypbpr_en = cfg[5]; -wire csync = cfg[3]; -`ifndef LITE +wire dvi_mode = cfg[7]; +wire audio_96k = cfg[6]; +wire ypbpr_en = cfg[5]; +wire csync = cfg[3]; wire vga_scaler= cfg[2]; -`endif reg cfg_custom_t = 0; reg [5:0] cfg_custom_p1; @@ -206,7 +204,19 @@ reg [31:0] cfg_custom_p2; reg [4:0] vol_att = 0; -reg vip_newcfg = 0; +reg [6:0] coef_addr; +reg [8:0] coef_data; +reg coef_wr = 0; + +`ifndef LITE +reg vip_newcfg = 0; +reg coef_set = 0; +`endif + +wire [7:0] ARX, ARY; +reg [11:0] VSET = 0; +reg [2:0] scaler_flt; + always@(posedge clk_sys) begin reg [7:0] cmd; reg has_cmd; @@ -214,8 +224,14 @@ always@(posedge clk_sys) begin reg [7:0] cnt = 0; old_strobe <= io_strobe; + coef_wr <= 0; - if(~io_uio) has_cmd <= 0; + if(~io_uio) begin + has_cmd <= 0; +`ifndef LITE + if(has_cmd && cmd == 'h2A) coef_set <= ~coef_set; +`endif + end else if(~old_strobe & io_strobe) begin if(!has_cmd) begin @@ -232,16 +248,18 @@ always@(posedge clk_sys) begin cfg_set <= 0; cnt <= cnt + 1'd1; if(cnt<8) begin +`ifndef LITE if(!cnt) vip_newcfg <= ~cfg_ready; +`endif case(cnt) - 0: if(WIDTH != io_din[11:0]) begin WIDTH <= io_din[11:0]; vip_newcfg <= 1; end - 1: if(HFP != io_din[11:0]) begin HFP <= io_din[11:0]; vip_newcfg <= 1; end - 2: if(HS != io_din[11:0]) begin HS <= io_din[11:0]; vip_newcfg <= 1; end - 3: if(HBP != io_din[11:0]) begin HBP <= io_din[11:0]; vip_newcfg <= 1; end - 4: if(HEIGHT != io_din[11:0]) begin HEIGHT <= io_din[11:0]; vip_newcfg <= 1; end - 5: if(VFP != io_din[11:0]) begin VFP <= io_din[11:0]; vip_newcfg <= 1; end - 6: if(VS != io_din[11:0]) begin VS <= io_din[11:0]; vip_newcfg <= 1; end - 7: if(VBP != io_din[11:0]) begin VBP <= io_din[11:0]; vip_newcfg <= 1; end + 0: if(WIDTH != io_din[11:0]) begin WIDTH <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 1: if(HFP != io_din[11:0]) begin HFP <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 2: if(HS != io_din[11:0]) begin HS <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 3: if(HBP != io_din[11:0]) begin HBP <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 4: if(HEIGHT != io_din[11:0]) begin HEIGHT <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 5: if(VFP != io_din[11:0]) begin VFP <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 6: if(VS != io_din[11:0]) begin VS <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end + 7: if(VBP != io_din[11:0]) begin VBP <= io_din[11:0]; `ifndef LITE vip_newcfg <= 1; `endif end endcase if(cnt == 1) begin cfg_custom_p1 <= 0; @@ -262,6 +280,8 @@ always@(posedge clk_sys) begin if(cmd == 'h25) {led_overtake, led_state} <= io_din; if(cmd == 'h26) vol_att <= io_din[4:0]; if(cmd == 'h27) VSET <= io_din[11:0]; + if(cmd == 'h2A) {coef_wr,coef_addr,coef_data} <= {1'b1,io_din}; + if(cmd == 'h2B) scaler_flt <= io_din[2:0]; end end end @@ -350,6 +370,16 @@ vip vip .ram2_byteenable(0), .ram2_write(0), + .uart_ri(0), + .uart_dsr(uart_dsr), + .uart_dcd(uart_dsr), + .uart_dtr(uart_dtr), + + .uart_cts(uart_cts), + .uart_rts(uart_rts), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + //Video input .in_clk(clk_vid), .in_data({r_out, g_out, b_out}), @@ -357,7 +387,7 @@ vip vip .in_v_sync(vs), .in_h_sync(hs), .in_ce(ce_pix), - .in_f(0), + .in_f(f1), //HDMI output .hdmi_clk(iHdmiClk), @@ -372,7 +402,6 @@ wire ctl_write; wire [31:0] ctl_writedata; wire ctl_waitrequest; wire ctl_reset; -wire [7:0] ARX, ARY; vip_config vip_config ( @@ -393,6 +422,13 @@ vip_config vip_config .VS(VS), .VSET(VSET), + .coef_set(coef_set), + .coef_clk(clk_sys), + .coef_addr(coef_addr), + .coef_data(coef_data), + .coef_wr(coef_wr), + .scaler_flt(scaler_flt), + .address(ctl_address), .write(ctl_write), .writedata(ctl_writedata), @@ -405,71 +441,6 @@ vip_config vip_config `ifdef LITE -wire [11:0] x; -wire [11:0] y; - -sync_vg #(.X_BITS(12), .Y_BITS(12)) sync_vg -( - .clk(iHdmiClk), - .reset(reset), - .v_total(HEIGHT+VFP+VBP+VS), - .v_fp(VFP), - .v_bp(VBP), - .v_sync(VS), - .h_total(WIDTH+HFP+HBP+HS), - .h_fp(HFP), - .h_bp(HBP), - .h_sync(HS), - .hv_offset(0), - .vde_out(vde), - .hde_out(hde), - .vs_out(vs_hdmi), - .v_count_out(), - .h_count_out(), - .x_out(x), - .y_out(y), - .hs_out(hs_hdmi) -); - -wire vde, hde; -wire vs_hdmi; -wire hs_hdmi; - -`ifndef HDMI_LITE - -pattern_vg -#( - .B(8), // Bits per channel - .X_BITS(12), - .Y_BITS(12), - .FRACTIONAL_BITS(12) // Number of fractional bits for ramp pattern -) -pattern_vg -( - .reset(reset), - .clk_in(iHdmiClk), - .x(x), - .y(y), - .vn_in(vs_hdmi), - .hn_in(hs_hdmi), - .dn_in(vde & hde), - .r_in(0), - .g_in(0), - .b_in(0), - .vn_out(HDMI_TX_VS), - .hn_out(HDMI_TX_HS), - .den_out(hdmi_de), - .r_out(hdmi_data[23:16]), - .g_out(hdmi_data[15:8]), - .b_out(hdmi_data[7:0]), - .total_active_pix(WIDTH), - .total_active_lines(HEIGHT), - .pattern(4), - .ramp_step(20'h0333) -); - -`endif - wire reset; sysmem_lite sysmem ( @@ -506,10 +477,18 @@ sysmem_lite sysmem .ram2_read(0), .ram2_writedata(0), .ram2_byteenable(0), - .ram2_write(0) + .ram2_write(0), + + .uart_ri(0), + .uart_dsr(uart_dsr), + .uart_dcd(uart_dsr), + .uart_dtr(uart_dtr), + + .uart_cts(uart_cts), + .uart_rts(uart_rts), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), -`ifdef HDMI_LITE - , // HDMI frame buffer .vbuf_clk(clk_ctl), .vbuf_address(vbuf_address), @@ -534,47 +513,103 @@ wire [127:0] vbuf_writedata; wire [15:0] vbuf_byteenable; wire vbuf_write; -assign HDMI_TX_VS = vs_hdmi; -assign HDMI_TX_HS = hs_hdmi; - -hdmi_lite hdmi_lite +ascal +#( + .RAMBASE(32'h20000000), + .N_DW(128), + .N_AW(28) +) +ascal ( - .reset(reset), + .reset_na (~reset_req), + .run (1), + .freeze (0), - .clk_video(clk_vid), - .ce_pixel(ce_pix), - .video_vs(vs), - .video_de(de), - .video_d({r_out,g_out,b_out}), + .i_clk (clk_vid), + .i_ce (ce_pix), + .i_r (r_out), + .i_g (g_out), + .i_b (b_out), + .i_hs (hs), + .i_vs (vs), + .i_fl (f1), + .i_de (de), + .iauto (1), + .himin (0), + .himax (0), + .vimin (0), + .vimax (0), - .clk_hdmi(HDMI_TX_CLK), - .hdmi_hde(hde), - .hdmi_vde(vde), - .hdmi_d(hdmi_data), - .hdmi_de(hdmi_de), + .o_clk (iHdmiClk), + .o_ce (1), + .o_r (hdmi_data[23:16]), + .o_g (hdmi_data[15:8]), + .o_b (hdmi_data[7:0]), + .o_hs (HDMI_TX_HS), + .o_vs (HDMI_TX_VS), + .o_de (hdmi_de), + .htotal (WIDTH+HFP+HBP+HS), + .hsstart(WIDTH + HFP), + .hsend (WIDTH + HFP + HS), + .hdisp (WIDTH), + .hmin (hmin), + .hmax (hmax), + .vtotal (HEIGHT+VFP+VBP+VS), + .vsstart(HEIGHT + VFP), + .vsend (HEIGHT + VFP + VS), + .vdisp (HEIGHT), + .vmin (vmin), + .vmax (vmax), - .screen_w(WIDTH), - .screen_h(HEIGHT), - .quadbuf(1), - .scale_x(0), - .scale_y(0), - .scale_auto(1), - - .clk_vbuf(clk_ctl), - .vbuf_address(vbuf_address), - .vbuf_burstcount(vbuf_burstcount), - .vbuf_waitrequest(vbuf_waitrequest), - .vbuf_writedata(vbuf_writedata), - .vbuf_byteenable(vbuf_byteenable), - .vbuf_write(vbuf_write), - .vbuf_readdata(vbuf_readdata), - .vbuf_readdatavalid(vbuf_readdatavalid), - .vbuf_read(vbuf_read) - -`endif + .mode ({1'b1,scaler_flt,2'b00}), + .poly_clk (clk_sys), + .poly_a (coef_addr), + .poly_dw (coef_data), + .poly_wr (coef_wr), + .avl_clk (clk_ctl), + .avl_waitrequest (vbuf_waitrequest), + .avl_readdata (vbuf_readdata), + .avl_readdatavalid(vbuf_readdatavalid), + .avl_burstcount (vbuf_burstcount), + .avl_writedata (vbuf_writedata), + .avl_address (vbuf_address), + .avl_write (vbuf_write), + .avl_read (vbuf_read), + .avl_byteenable (vbuf_byteenable) ); +reg [11:0] hmin; +reg [11:0] hmax; +reg [11:0] vmin; +reg [11:0] vmax; + +always @(posedge clk_vid) begin + reg [31:0] wcalc; + reg [31:0] hcalc; + reg [2:0] state; + reg [11:0] videow; + reg [11:0] videoh; + + state <= state + 1'd1; + case(state) + 0: begin + wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY; + hcalc <= (WIDTH*ARY)/ARX; + end + 6: begin + videow <= (!VSET && (wcalc > WIDTH)) ? WIDTH : wcalc[11:0]; + videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0]; + end + 7: begin + hmin <= ((WIDTH - videow)>>1); + hmax <= ((WIDTH - videow)>>1) + videow - 1'd1; + vmin <= ((HEIGHT - videoh)>>1); + vmax <= ((HEIGHT - videoh)>>1) + videoh - 1'd1; + end + endcase +end + `endif @@ -598,7 +633,6 @@ reg [11:0] HEIGHT = 1080; reg [11:0] VFP = 4; reg [11:0] VS = 5; reg [11:0] VBP = 36; -reg [11:0] VSET = 0; wire [63:0] reconfig_to_pll; wire [63:0] reconfig_from_pll; @@ -664,8 +698,20 @@ hdmi_config hdmi_config ); wire [23:0] hdmi_data; +wire [23:0] hdmi_data_sl; wire hdmi_de; +scanlines #(1) HDMI_scanlines +( + .clk(iHdmiClk), + + .scanlines(scanlines), + .din(hdmi_data), + .dout(hdmi_data_sl), + .hs(HDMI_TX_HS), + .vs(HDMI_TX_VS) +); + osd hdmi_osd ( .clk_sys(clk_sys), @@ -675,7 +721,7 @@ osd hdmi_osd .io_din(io_din), .clk_video(iHdmiClk), - .din(hdmi_data), + .din(hdmi_data_sl), .dout(HDMI_TX_D), .de_in(hdmi_de), .de_out(HDMI_TX_DE) @@ -700,7 +746,19 @@ i2s i2s ///////////////////////// VGA output ////////////////////////////////// -wire [23:0] vga_q; +wire [23:0] vga_data_sl; + +scanlines #(0) VGA_scanlines +( + .clk(clk_vid), + + .scanlines(scanlines), + .din(de ? {r_out, g_out, b_out} : 24'd0), + .dout(vga_data_sl), + .hs(hs1), + .vs(vs1) +); + osd vga_osd ( .clk_sys(clk_sys), @@ -710,11 +768,12 @@ osd vga_osd .io_din(io_din), .clk_video(clk_vid), - .din(de ? {r_out, g_out, b_out} : 24'd0), + .din(vga_data_sl), .dout(vga_q), .de_in(de) ); +wire [23:0] vga_q; wire [23:0] vga_o; vga_out vga_out @@ -722,20 +781,11 @@ vga_out vga_out .ypbpr_full(1), .ypbpr_en(ypbpr_en), .dout(vga_o), -`ifdef LITE - .din(vga_q) -`else .din(vga_scaler ? {24{HDMI_TX_DE}} & HDMI_TX_D : vga_q) -`endif ); -`ifdef LITE - wire vs1 = vs; - wire hs1 = hs; -`else - wire vs1 = vga_scaler ? HDMI_TX_VS : vs; - wire hs1 = vga_scaler ? HDMI_TX_HS : hs; -`endif +wire vs1 = vga_scaler ? HDMI_TX_VS : vs; +wire hs1 = vga_scaler ? HDMI_TX_HS : hs; assign VGA_VS = VGA_EN ? 1'bZ : csync ? 1'b1 : ~vs1; assign VGA_HS = VGA_EN ? 1'bZ : csync ? ~(vs1 ^ hs1) : ~hs1; @@ -832,7 +882,8 @@ wire signed [15:0] audio_ls, audio_rs; wire audio_s; wire [1:0] audio_mix; wire [7:0] r_out, g_out, b_out; -wire vs, hs, de; +wire vs, hs, de, f1; +wire [1:0] scanlines; wire clk_sys, clk_vid, ce_pix; wire ram_clk; @@ -851,8 +902,15 @@ wire [1:0] led_power; wire [1:0] led_disk; wire vs_emu, hs_emu; -sync_fix sync_v(FPGA_CLK3_50, vs_emu, vs); -sync_fix sync_h(FPGA_CLK3_50, hs_emu, hs); +sync_fix sync_v(clk_vid, vs_emu, vs); +sync_fix sync_h(clk_vid, hs_emu, hs); + +wire uart_dtr; +wire uart_dsr; +wire uart_cts; +wire uart_rts; +wire uart_rxd; +wire uart_txd; emu emu ( @@ -869,15 +927,15 @@ emu emu .VGA_HS(hs_emu), .VGA_VS(vs_emu), .VGA_DE(de), + .VGA_F1(f1), + .VGA_SL(scanlines), .LED_USER(led_user), .LED_POWER(led_power), .LED_DISK(led_disk), -`ifndef LITE .VIDEO_ARX(ARX), .VIDEO_ARY(ARY), -`endif .AUDIO_L(audio_ls), .AUDIO_R(audio_rs), @@ -918,7 +976,14 @@ emu emu .SDRAM_nRAS(SDRAM_nRAS), .SDRAM_nCAS(SDRAM_nCAS), .SDRAM_CLK(SDRAM_CLK), - .SDRAM_CKE(SDRAM_CKE) + .SDRAM_CKE(SDRAM_CKE), + + .UART_CTS(uart_rts), + .UART_RTS(uart_cts), + .UART_RXD(uart_txd), + .UART_TXD(uart_rxd), + .UART_DTR(uart_dsr), + .UART_DSR(uart_dtr) ); endmodule diff --git a/sys/sysmem.sv b/sys/sysmem.sv index 0f60f65..d882843 100644 --- a/sys/sysmem.sv +++ b/sys/sysmem.sv @@ -38,7 +38,18 @@ module sysmem_lite input vbuf_read, // .read input [127:0] vbuf_writedata, // .writedata input [15:0] vbuf_byteenable, // .byteenable - input vbuf_write // .write + input vbuf_write, // .write + + input uart_cts, // uart.cts + input uart_dsr, // .dsr + input uart_dcd, // .dcd + input uart_ri, // .ri + output uart_dtr, // .dtr + output uart_rts, // .rts + output uart_out1_n, // .out1_n + output uart_out2_n, // .out2_n + input uart_rxd, // .rxd + output uart_txd // .txd ); assign ctl_clock = clk_vip_clk; @@ -82,7 +93,17 @@ sysmem_HPS_fpga_interfaces fpga_interfaces ( .f2h_sdram2_READ (ram2_read), // .read .f2h_sdram2_WRITEDATA (ram2_writedata), // .writedata .f2h_sdram2_BYTEENABLE (ram2_byteenable), // .byteenable - .f2h_sdram2_WRITE (ram2_write) // .write + .f2h_sdram2_WRITE (ram2_write), // .write + .uart_cts (uart_cts), + .uart_dsr (uart_dsr), + .uart_dcd (uart_dcd), + .uart_ri (uart_ri), + .uart_dtr (uart_dtr), + .uart_rts (uart_rts), + .uart_out1_n (uart_out1_n), + .uart_out2_n (uart_out2_n), + .uart_rxd (uart_rxd), + .uart_txd (uart_txd) ); reset_source reset_source ( @@ -100,105 +121,6 @@ reset_source reset_source ( endmodule -`timescale 1 ps / 1 ps -module sysmem -( - input ramclk1_clk, // ramclk1.clk - input [28:0] ram1_address, // ram1.address - input [7:0] ram1_burstcount, // .burstcount - output ram1_waitrequest, // .waitrequest - output [63:0] ram1_readdata, // .readdata - output ram1_readdatavalid, // .readdatavalid - input ram1_read, // .read - input [63:0] ram1_writedata, // .writedata - input [7:0] ram1_byteenable, // .byteenable - input ram1_write, // .write - - input ramclk2_clk, // ramclk2.clk - input [28:0] ram2_address, // ram2.address - input [7:0] ram2_burstcount, // .burstcount - output ram2_waitrequest, // .waitrequest - output [63:0] ram2_readdata, // .readdata - output ram2_readdatavalid, // .readdatavalid - input ram2_read, // .read - input [63:0] ram2_writedata, // .writedata - input [7:0] ram2_byteenable, // .byteenable - input ram2_write, // .write - - input reset_cold_req, // reset.cold_req - output reset_reset, // .reset - input reset_reset_req, // .reset_req - input reset_warm_req, // .warm_req - - input [27:0] ram_vip_address, // ram_vip.address - input [7:0] ram_vip_burstcount, // .burstcount - output ram_vip_waitrequest, // .waitrequest - output [127:0] ram_vip_readdata, // .readdata - output ram_vip_readdatavalid, // .readdatavalid - input ram_vip_read, // .read - input [127:0] ram_vip_writedata, // .writedata - input [15:0] ram_vip_byteenable, // .byteenable - input ram_vip_write, // .write - - output clk_vip_clk, // clk_vip.clk - output reset_vip_reset // reset_vip.reset -); - -wire hps_h2f_reset_reset; // HPS:h2f_rst_n -> Reset_Source:reset_hps -wire reset_source_reset_cold_reset; // Reset_Source:reset_cold -> HPS:f2h_cold_rst_req_n -wire reset_source_reset_warm_reset; // Reset_Source:reset_warm -> HPS:f2h_warm_rst_req_n - -sysmem_HPS_fpga_interfaces fpga_interfaces ( - .f2h_cold_rst_req_n (~reset_source_reset_cold_reset), // f2h_cold_reset_req.reset_n - .f2h_warm_rst_req_n (~reset_source_reset_warm_reset), // f2h_warm_reset_req.reset_n - .h2f_user0_clk (clk_vip_clk), // h2f_user0_clock.clk - .h2f_rst_n (hps_h2f_reset_reset), // h2f_reset.reset_n - .f2h_sdram0_clk (clk_vip_clk), // f2h_sdram0_clock.clk - .f2h_sdram0_ADDRESS (ram_vip_address), // f2h_sdram0_data.address - .f2h_sdram0_BURSTCOUNT (ram_vip_burstcount), // .burstcount - .f2h_sdram0_WAITREQUEST (ram_vip_waitrequest), // .waitrequest - .f2h_sdram0_READDATA (ram_vip_readdata), // .readdata - .f2h_sdram0_READDATAVALID (ram_vip_readdatavalid), // .readdatavalid - .f2h_sdram0_READ (ram_vip_read), // .read - .f2h_sdram0_WRITEDATA (ram_vip_writedata), // .writedata - .f2h_sdram0_BYTEENABLE (ram_vip_byteenable), // .byteenable - .f2h_sdram0_WRITE (ram_vip_write), // .write - .f2h_sdram1_clk (ramclk1_clk), // f2h_sdram1_clock.clk - .f2h_sdram1_ADDRESS (ram1_address), // f2h_sdram1_data.address - .f2h_sdram1_BURSTCOUNT (ram1_burstcount), // .burstcount - .f2h_sdram1_WAITREQUEST (ram1_waitrequest), // .waitrequest - .f2h_sdram1_READDATA (ram1_readdata), // .readdata - .f2h_sdram1_READDATAVALID (ram1_readdatavalid), // .readdatavalid - .f2h_sdram1_READ (ram1_read), // .read - .f2h_sdram1_WRITEDATA (ram1_writedata), // .writedata - .f2h_sdram1_BYTEENABLE (ram1_byteenable), // .byteenable - .f2h_sdram1_WRITE (ram1_write), // .write - .f2h_sdram2_clk (ramclk2_clk), // f2h_sdram2_clock.clk - .f2h_sdram2_ADDRESS (ram2_address), // f2h_sdram2_data.address - .f2h_sdram2_BURSTCOUNT (ram2_burstcount), // .burstcount - .f2h_sdram2_WAITREQUEST (ram2_waitrequest), // .waitrequest - .f2h_sdram2_READDATA (ram2_readdata), // .readdata - .f2h_sdram2_READDATAVALID (ram2_readdatavalid), // .readdatavalid - .f2h_sdram2_READ (ram2_read), // .read - .f2h_sdram2_WRITEDATA (ram2_writedata), // .writedata - .f2h_sdram2_BYTEENABLE (ram2_byteenable), // .byteenable - .f2h_sdram2_WRITE (ram2_write) // .write -); - -reset_source reset_source ( - .clk (clk_vip_clk), // clock.clk - .reset_hps (~hps_h2f_reset_reset), // reset_hps.reset - .reset_sys (reset_vip_reset), // reset_sys.reset - .cold_req (reset_cold_req), // reset_ctl.cold_req - .reset (reset_reset), // .reset - .reset_req (reset_reset_req), // .reset_req - .warm_req (reset_warm_req), // .warm_req - .reset_warm (reset_source_reset_warm_reset), // reset_warm.reset - .reset_cold (reset_source_reset_cold_reset) // reset_cold.reset -); - -endmodule - module sysmem_HPS_fpga_interfaces ( // h2f_reset @@ -254,6 +176,17 @@ module sysmem_HPS_fpga_interfaces // f2h_sdram2_clock ,input wire [1 - 1 : 0 ] f2h_sdram2_clk + + ,input uart_cts // uart.cts + ,input uart_dsr // .dsr + ,input uart_dcd // .dcd + ,input uart_ri // .ri + ,output uart_dtr // .dtr + ,output uart_rts // .rts + ,output uart_out1_n // .out1_n + ,output uart_out2_n // .out2_n + ,input uart_rxd // .rxd + ,output uart_txd // .txd ); @@ -527,5 +460,19 @@ cyclonev_hps_interface_fpga2sdram f2sdram( ,intermediate[4:4] // 0:0 }) ); + +cyclonev_hps_interface_peripheral_uart peripheral_uart1 +( + .txd(uart_txd) + ,.cts(uart_cts) + ,.out1_n(uart_out1_n) + ,.dtr(uart_dtr) + ,.rts(uart_rts) + ,.out2_n(uart_out2_n) + ,.rxd(uart_rxd) + ,.ri(uart_ri) + ,.dsr(uart_dsr) + ,.dcd(uart_dcd) +); endmodule diff --git a/sys/vip.qsys b/sys/vip.qsys index 47306be..32861bf 100644 --- a/sys/vip.qsys +++ b/sys/vip.qsys @@ -13,7 +13,15 @@ { datum _sortIndex { - value = "9"; + value = "10"; + type = "int"; + } + } + element Deinterlacer + { + datum _sortIndex + { + value = "4"; type = "int"; } } @@ -21,7 +29,7 @@ { datum _sortIndex { - value = "4"; + value = "5"; type = "int"; } } @@ -45,7 +53,7 @@ { datum _sortIndex { - value = "6"; + value = "7"; type = "int"; } } @@ -53,7 +61,7 @@ { datum _sortIndex { - value = "8"; + value = "9"; type = "int"; } } @@ -69,7 +77,7 @@ { datum _sortIndex { - value = "5"; + value = "6"; type = "int"; } } @@ -85,7 +93,7 @@ { datum _sortIndex { - value = "7"; + value = "8"; type = "int"; } } @@ -505,62 +513,6 @@ type = "String"; } } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } - element vip - { - datum _originalDeviceFamily - { - value = "Cyclone V"; - type = "String"; - } - } } ]]> @@ -586,8 +538,6 @@ - - @@ -597,13 +547,54 @@ internal="Reset_Source.reset_ctl" type="conduit" dir="end" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -772,8 +763,8 @@ - - + + @@ -880,7 +871,7 @@ - + @@ -890,7 +881,7 @@ - + ]]> @@ -901,8 +892,8 @@ - - + + @@ -914,13 +905,13 @@ - - + + ]]> - + @@ -1027,6 +1018,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + end="Deinterlacer.din" /> + + - + + + + + >2] == 22'h3FFFFF) begin - state <= 0; - newres <= 0; - end - else begin - writedata <= 0; - {write, address, writedata[11:0]} <= init[state>>2]; + if(state) begin + state <= state + 1'd1; + if((state&3)==3) begin + if(init[state>>2] == 22'h3FFFFF) begin + state <= 0; + newres <= 0; + coef_state <= 1; + coef_a <= 0; + end + else begin + writedata <= 0; + {write, address, writedata[11:0]} <= init[state>>2]; + end end end + else begin + case(coef_state) + 1,3: coef_state <= coef_state + 1'd1; + 2: begin + address <= 8; + writedata <= 0; + writedata[0] <= bank; + write <= 1; + coef_state <= coef_state + 1'd1; + end + 4: begin + address <= 10; + writedata <= 0; + writedata[0] <= bank; + write <= 1; + coef_state <= coef_state + 1'd1; + end + 5,7,9,11: coef_state <= coef_state + 1'd1; + 6,8,10,12: + begin + coef_state <= coef_state + 1'd1; + coef_a <= coef_a + 1'd1; + coef_n <= coef_a; + address <= 9'd14 + coef_a[1:0]; + writedata <= coef_q; + write <= 1; + end + 13: begin + coef_state <= (&coef_n) ? 5'd14 : 5'd5; + address <= 9'd12 + coef_n[6]; + writedata <= coef_n[5:2]; + write <= 1; + end + 14,16: coef_state <= coef_state + 1'd1; + 15: begin + address <= 9; + writedata <= 0; + writedata[0] <= bank; + write <= 1; + coef_state <= coef_state + 1'd1; + end + 17: begin + address <= 11; + writedata <= 0; + writedata[0] <= bank; + write <= 1; + bank <= ~bank; + coef_state <= coef_state + 1'd1; + end + 18: coef_state <= 0; + endcase; + end end end endmodule + +module coeffbuf +( + input wrclock, + input [7:0] wraddress, + input [8:0] data, + input wren, + + input rdclock, + input [7:0] rdaddress, + output[8:0] q +); + +altsyncram altsyncram_component ( + .address_a (wraddress), + .address_b (rdaddress), + .clock0 (wrclock), + .clock1 (rdclock), + .data_a (data), + .wren_a (wren), + .q_b (q), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({9{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); +defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK1", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 256, + altsyncram_component.numwords_b = 256, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.init_file = "coeff.mif", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.widthad_a = 8, + altsyncram_component.widthad_b = 8, + altsyncram_component.width_a = 9, + altsyncram_component.width_b = 9, + altsyncram_component.width_byteena_a = 1; + + +endmodule +