diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-03-13 18:26:54 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-03-13 18:26:54 +0100 |
commit | 74ec145c5e44a51789e9117b1ae93dfd7be24d86 (patch) | |
tree | 65861f837c708a8ff32ebcdfd389094492085ba9 | |
parent | b247b52429f2fc6aecd29539ec5afa0d47218147 (diff) |
fix display upscaler (output working!)
-rw-r--r-- | basys3/basys3.srcs/ppu_dispctl.vhd | 96 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_dispctl_demo_top.vhd | 15 | ||||
-rw-r--r-- | basys3/basys3.xpr | 68 | ||||
-rwxr-xr-x | test/upscaler/img2coe.py (renamed from test/upscaler/bitmap-ball.py) | 4 | ||||
-rw-r--r-- | test/upscaler/makefile | 4 |
5 files changed, 111 insertions, 76 deletions
diff --git a/basys3/basys3.srcs/ppu_dispctl.vhd b/basys3/basys3.srcs/ppu_dispctl.vhd index 1be0365..117b780 100644 --- a/basys3/basys3.srcs/ppu_dispctl.vhd +++ b/basys3/basys3.srcs/ppu_dispctl.vhd @@ -38,8 +38,7 @@ architecture Behavioral of ppu_dispctl is rstb_busy : out std_logic); end component; signal NPIXCLK, TPIXCLK : std_logic; - signal NHCOUNT, NVCOUNT, - THCOUNT, TVCOUNT: unsigned(PPU_VGA_SIGNAL_PIXEL_WIDTH-1 downto 0) := (others => '0'); + signal NHCOUNT, NVCOUNT : unsigned(PPU_VGA_SIGNAL_PIXEL_WIDTH-1 downto 0) := (others => '0'); signal ADDR_I, ADDR_O : std_logic_vector(PPU_DISPCTL_SLBUF_ADDR_WIDTH-1 downto 0); signal DATA_I, DATA_O : std_logic_vector(PPU_RGB_COLOR_OUTPUT_DEPTH-1 downto 0); signal T_POS_X : unsigned(PPU_SCREEN_T_POS_X_WIDTH-1 downto 0) := (others => '0'); -- real tiny x position @@ -52,75 +51,52 @@ architecture Behavioral of ppu_dispctl is signal NACTIVE, NHACTIVE, NVACTIVE : std_logic := '0'; signal TACTIVE, THACTIVE, TVACTIVE : std_logic := '0'; begin + -- scanline buffer data in + DATA_I <= RI & GI & BI; + ADDR_I <= std_logic_vector(resize(T_POS_X, ADDR_I'length)) when T_POS_Y(0) = '0' else std_logic_vector(resize(T_POS_X, ADDR_I'length) + PPU_SCREEN_WIDTH); + + T_POS_Y <= U_POS_Y; -- tiny VCOUNT and HCOUNT process(TPIXCLK, RESET) - variable TMP_THCOUNT, TMP_TVCOUNT : unsigned(PPU_VGA_SIGNAL_PIXEL_WIDTH-1 downto 0) := (others => '0'); + variable TMP_T_POS_X : unsigned(PPU_SCREEN_T_POS_X_WIDTH-1 downto 0) := (others => '0'); variable TMP_THBLANK, TMP_TVBLANK : std_logic := '0'; begin - TVCOUNT <= TMP_TVCOUNT; - THCOUNT <= TMP_THCOUNT; - - T_POS_X <= resize(TMP_THCOUNT - (PPU_VGA_H_PORCH_BACK / 4), T_POS_X'length) when N_POS_Y(0) = to_unsigned(PPU_VGA_V_PORCH_BACK, 1)(0) else - resize(TMP_THCOUNT - ((PPU_VGA_H_PORCH_BACK + PPU_VGA_H_BLANK) / 4), T_POS_X'length); -- divide tiny x equally over two native scanlines - T_POS_Y <= resize(TMP_TVCOUNT - (PPU_VGA_V_PORCH_BACK / 2), T_POS_Y'length); - - THBLANK <= TMP_THBLANK; - TVBLANK <= TMP_TVBLANK; - - -- scanline buffer data in - DATA_I <= RI & GI & BI; - ADDR_I <= std_logic_vector(resize(T_POS_X, ADDR_I'length)) when T_POS_Y(0) = '0' else std_logic_vector(resize(T_POS_X, ADDR_I'length) + PPU_SCREEN_WIDTH); - if RESET = '1' then - TMP_THCOUNT := (others => '0'); - TMP_TVCOUNT := (others => '0'); - TMP_THBLANK := '0'; - TMP_TVBLANK := '0'; + TMP_THBLANK := '0'; -- TODO + TMP_TVBLANK := '0'; -- TODO elsif rising_edge(TPIXCLK) then - TMP_THCOUNT := TMP_THCOUNT + 1; - if TMP_THCOUNT >= PPU_VGA_H_TOTAL then - TMP_THCOUNT := (others => '0'); + T_POS_X <= TMP_T_POS_X; - TMP_TVCOUNT := TMP_TVCOUNT + 1; - if TMP_TVCOUNT >= PPU_VGA_V_TOTAL then - TMP_TVCOUNT := (others => '0'); - end if; + THBLANK <= TMP_THBLANK; + TVBLANK <= TMP_TVBLANK; - -- vertical display area (active) - if TMP_TVCOUNT = PPU_VGA_V_PORCH_BACK then TMP_TVBLANK := '0'; end if; - if TMP_TVCOUNT = PPU_VGA_V_PORCH_BACK + PPU_VGA_V_ACTIVE then TMP_TVBLANK := '1'; end if; + if NACTIVE = '1' then + TMP_T_POS_X := TMP_T_POS_X + 1; + if TMP_T_POS_X >= PPU_SCREEN_WIDTH then + TMP_T_POS_X := (others => '0'); + end if; end if; - - -- horizontal display area (active) - if TMP_THCOUNT = PPU_VGA_H_PORCH_BACK then TMP_THBLANK := '0'; end if; - if TMP_THCOUNT = PPU_VGA_H_PORCH_BACK + PPU_VGA_H_ACTIVE then TMP_THBLANK := '1'; end if; end if; end process; + X <= std_logic_vector(T_POS_X) when NACTIVE = '1' else (others => '0'); + Y <= std_logic_vector(T_POS_Y) when NACTIVE = '1' else (others => '0'); + + U_POS_X <= resize(N_POS_X(N_POS_X'length-1 downto 1), U_POS_X'length); + U_POS_Y <= resize(N_POS_Y(N_POS_Y'length-1 downto 1), U_POS_Y'length); + + -- scanline buffer data out + ADDR_O <= std_logic_vector(resize(U_POS_X, ADDR_I'length)) when U_POS_Y(0) = '1' else std_logic_vector(resize(U_POS_X, ADDR_I'length) + PPU_SCREEN_WIDTH); + RO <= DATA_O(11 downto 8) when NACTIVE = '1' else (others => '0'); + GO <= DATA_O(7 downto 4) when NACTIVE = '1' else (others => '0'); + BO <= DATA_O(3 downto 0) when NACTIVE = '1' else (others => '0'); + -- native (+upscaled) VCOUNT and HCOUNT process(NPIXCLK, RESET) variable TMP_NHCOUNT, TMP_NVCOUNT : unsigned(PPU_VGA_SIGNAL_PIXEL_WIDTH-1 downto 0) := (others => '0'); variable TMP_NHACTIVE, TMP_NVACTIVE : std_logic := '0'; variable TMP_NHSYNC, TMP_NVSYNC : std_logic := '0'; begin - NVCOUNT <= TMP_NVCOUNT; - NHCOUNT <= TMP_NHCOUNT; - NHACTIVE <= TMP_NHACTIVE; - NVACTIVE <= TMP_NVACTIVE; - NACTIVE <= TMP_NHACTIVE and TMP_NVACTIVE; - NVSYNC <= TMP_NVSYNC; - NHSYNC <= TMP_NHSYNC; - N_POS_X <= resize(TMP_NHCOUNT - PPU_VGA_H_PORCH_BACK, N_POS_X'length) when TMP_NHACTIVE = '1' else (others => '0'); - N_POS_Y <= resize(TMP_NVCOUNT - PPU_VGA_V_PORCH_BACK, N_POS_Y'length) when TMP_NVACTIVE = '1' else (others => '0'); - U_POS_X <= resize(N_POS_X(N_POS_X'length-1 downto 1), U_POS_X'length); - U_POS_Y <= resize(N_POS_Y(N_POS_Y'length-1 downto 1), U_POS_Y'length); - - -- scanline buffer data out - ADDR_O <= std_logic_vector(resize(U_POS_X, ADDR_I'length)) when U_POS_Y(0) = '0' else std_logic_vector(resize(U_POS_X, ADDR_I'length) + PPU_SCREEN_WIDTH); - RO <= DATA_O(11 downto 8) when NACTIVE = '1' else (others => '0'); - GO <= DATA_O(7 downto 4) when NACTIVE = '1' else (others => '0'); - BO <= DATA_O(3 downto 0) when NACTIVE = '1' else (others => '0'); - if RESET = '1' then TMP_NHCOUNT := (others => '0'); TMP_NVCOUNT := (others => '0'); @@ -129,6 +105,17 @@ begin TMP_NVSYNC := '0'; TMP_NHSYNC := '0'; elsif rising_edge(NPIXCLK) then + -- sync write (needs to be here to happen on rising edge) + NVCOUNT <= TMP_NVCOUNT; + NHCOUNT <= TMP_NHCOUNT; + NHACTIVE <= TMP_NHACTIVE; + NVACTIVE <= TMP_NVACTIVE; + NACTIVE <= TMP_NHACTIVE and TMP_NVACTIVE; + NVSYNC <= TMP_NVSYNC; + NHSYNC <= TMP_NHSYNC; + N_POS_X <= resize(TMP_NHCOUNT - PPU_VGA_H_PORCH_BACK, N_POS_X'length) when TMP_NHACTIVE = '1' else (others => '0'); + N_POS_Y <= resize(TMP_NVCOUNT - PPU_VGA_V_PORCH_BACK, N_POS_Y'length) when TMP_NVACTIVE = '1' else (others => '0'); + -- horizontal count (pixel) TMP_NHCOUNT := TMP_NHCOUNT + 1; if TMP_NHCOUNT >= PPU_VGA_H_TOTAL then @@ -159,9 +146,6 @@ begin end if; end process; - X <= std_logic_vector(T_POS_X) when NACTIVE = '1' else (others => '0'); - Y <= std_logic_vector(T_POS_Y) when NACTIVE = '1' else (others => '0'); - scanline_buffer : component ppu_dispctl_slbuf port map( clka => SYSCLK, wea => (others => PREADY), diff --git a/basys3/basys3.srcs/ppu_dispctl_demo_top.vhd b/basys3/basys3.srcs/ppu_dispctl_demo_top.vhd index 9a0643e..dcbe100 100644 --- a/basys3/basys3.srcs/ppu_dispctl_demo_top.vhd +++ b/basys3/basys3.srcs/ppu_dispctl_demo_top.vhd @@ -32,6 +32,7 @@ architecture Behavioral of ppu_dispctl_demo is addra : in std_logic_vector (16 downto 0); douta : out std_logic_vector (11 downto 0)); end component; + signal PREADY : std_logic := '0'; signal ADDR : std_logic_vector (16 downto 0); signal DATA : std_logic_vector (11 downto 0); signal X : std_logic_vector(PPU_POS_H_WIDTH-1 downto 0); @@ -41,7 +42,17 @@ architecture Behavioral of ppu_dispctl_demo is alias DATA_G is DATA(7 downto 4); alias DATA_B is DATA(3 downto 0); begin - ADDR <= std_logic_vector(resize(unsigned(X) + unsigned(Y) * to_unsigned(PPU_SCREEN_WIDTH, ADDR'length), ADDR'length)); + ADDR <= std_logic_vector(resize(unsigned(X) + (unsigned(Y) * to_unsigned(PPU_SCREEN_WIDTH, ADDR'length)), ADDR'length)); + + process(CLK100) + variable counter : unsigned(3 downto 0) := (others => '0'); + begin + if rising_edge(CLK100) then + counter := counter + 1; + if counter = 5 then PREADY <= '1'; end if; + if counter = 6 then PREADY <= '0'; end if; + end if; + end process; test_img : component ppu_dispctl_test_img port map( clka => CLK100, @@ -51,7 +62,7 @@ begin display_controller : component ppu_dispctl port map( SYSCLK => CLK100, RESET => RESET, - PREADY => '1', + PREADY => PREADY, X => X, Y => Y, RI => DATA_R, diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr index a277fdc..a6d7041 100644 --- a/basys3/basys3.xpr +++ b/basys3/basys3.xpr @@ -61,20 +61,20 @@ <Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/> <Option Name="EnableBDX" Val="FALSE"/> <Option Name="DSABoardId" Val="basys3"/> - <Option Name="WTXSimLaunchSim" Val="244"/> + <Option Name="WTXSimLaunchSim" Val="270"/> <Option Name="WTModelSimLaunchSim" Val="0"/> <Option Name="WTQuestaLaunchSim" Val="0"/> <Option Name="WTIesLaunchSim" Val="0"/> <Option Name="WTVcsLaunchSim" Val="0"/> <Option Name="WTRivieraLaunchSim" Val="0"/> <Option Name="WTActivehdlLaunchSim" Val="0"/> - <Option Name="WTXSimExportSim" Val="17"/> - <Option Name="WTModelSimExportSim" Val="17"/> - <Option Name="WTQuestaExportSim" Val="17"/> + <Option Name="WTXSimExportSim" Val="19"/> + <Option Name="WTModelSimExportSim" Val="19"/> + <Option Name="WTQuestaExportSim" Val="19"/> <Option Name="WTIesExportSim" Val="0"/> - <Option Name="WTVcsExportSim" Val="17"/> - <Option Name="WTRivieraExportSim" Val="17"/> - <Option Name="WTActivehdlExportSim" Val="17"/> + <Option Name="WTVcsExportSim" Val="19"/> + <Option Name="WTRivieraExportSim" Val="19"/> + <Option Name="WTActivehdlExportSim" Val="19"/> <Option Name="GenerateIPUpgradeLog" Val="TRUE"/> <Option Name="XSimRadix" Val="hex"/> <Option Name="XSimTimeUnit" Val="ns"/> @@ -117,13 +117,6 @@ <Attr Name="UsedIn" Val="simulation"/> </FileInfo> </File> - <File Path="$PSRCDIR/sources_1/ip/ppu_dispctl_test_img/ppu_dispctl_test_img.xci"> - <FileInfo> - <Attr Name="UsedIn" Val="synthesis"/> - <Attr Name="UsedIn" Val="implementation"/> - <Attr Name="UsedIn" Val="simulation"/> - </FileInfo> - </File> <Config> <Option Name="DesignMode" Val="RTL"/> <Option Name="TopModule" Val="ppu_dispctl_demo"/> @@ -164,7 +157,7 @@ <Option Name="PamPseudoTop" Val="pseudo_tb"/> <Option Name="SrcSet" Val="sources_1"/> <Option Name="Incremental" Val="0"/> - <Option Name="xsim.simulate.runtime" Val="16 ms"/> + <Option Name="xsim.simulate.runtime" Val="18 ms"/> </Config> </FileSet> <FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1" RelGenDir="$PGENDIR/utils_1"> @@ -238,6 +231,20 @@ <Option Name="UseBlackboxStub" Val="1"/> </Config> </FileSet> + <FileSet Name="ppu_dispctl_test_img" Type="BlockSrcs" RelSrcDir="$PSRCDIR/ppu_dispctl_test_img" RelGenDir="$PGENDIR/ppu_dispctl_test_img"> + <File Path="$PSRCDIR/sources_1/ip/ppu_dispctl_test_img/ppu_dispctl_test_img.xci"> + <FileInfo> + <Attr Name="UsedIn" Val="synthesis"/> + <Attr Name="UsedIn" Val="implementation"/> + <Attr Name="UsedIn" Val="simulation"/> + </FileInfo> + </File> + <Config> + <Option Name="TopModule" Val="ppu_dispctl_test_img"/> + <Option Name="dataflowViewerSettings" Val="min_width=16"/> + <Option Name="UseBlackboxStub" Val="1"/> + </Config> + </FileSet> </FileSets> <Simulators> <Simulator Name="XSim"> @@ -331,6 +338,18 @@ <Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/> <RQSFiles/> </Run> + <Run Id="ppu_dispctl_test_img_synth_1" Type="Ft3:Synth" SrcSet="ppu_dispctl_test_img" Part="xc7a35tcpg236-1" ConstrsSet="ppu_dispctl_test_img" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/ppu_dispctl_test_img_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/ppu_dispctl_test_img_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/ppu_dispctl_test_img_synth_1"> + <Strategy Version="1" Minor="2"> + <StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"> + <Desc>Vivado Synthesis Defaults</Desc> + </StratHandle> + <Step Id="synth_design"/> + </Strategy> + <GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/> + <ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2022"/> + <Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/> + <RQSFiles/> + </Run> <Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35tcpg236-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1"> <Strategy Version="1" Minor="2"> <StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/> @@ -417,6 +436,25 @@ <Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/> <RQSFiles/> </Run> + <Run Id="ppu_dispctl_test_img_impl_1" Type="Ft2:EntireDesign" Part="xc7a35tcpg236-1" ConstrsSet="ppu_dispctl_test_img" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="ppu_dispctl_test_img_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/ppu_dispctl_test_img_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/ppu_dispctl_test_img_impl_1"> + <Strategy Version="1" Minor="2"> + <StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"> + <Desc>Default settings for Implementation.</Desc> + </StratHandle> + <Step Id="init_design"/> + <Step Id="opt_design"/> + <Step Id="power_opt_design"/> + <Step Id="place_design"/> + <Step Id="post_place_power_opt_design"/> + <Step Id="phys_opt_design"/> + <Step Id="route_design"/> + <Step Id="post_route_phys_opt_design"/> + <Step Id="write_bitstream"/> + </Strategy> + <ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2022"/> + <Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/> + <RQSFiles/> + </Run> </Runs> <Board> <Jumpers/> diff --git a/test/upscaler/bitmap-ball.py b/test/upscaler/img2coe.py index 85474f1..fb4c442 100755 --- a/test/upscaler/bitmap-ball.py +++ b/test/upscaler/img2coe.py @@ -9,8 +9,8 @@ def pixeldata(): pixels = image.load() pixarr = [] w,h = image.size - for x in range(w): - for y in range(h): + for y in range(h): + for x in range(w): color = pixels[x, y] crushed_color = ((color[0] >> 4) << 8 | (color[1] >> 4) << 4 | (color[2] >> 4) << 0) pixarr.append(crushed_color) diff --git a/test/upscaler/makefile b/test/upscaler/makefile index 072d5b2..393eda4 100644 --- a/test/upscaler/makefile +++ b/test/upscaler/makefile @@ -1,2 +1,4 @@ img.coe: img.png - ./bitmap-ball.py $< > $@ + +%.coe: %.png + ./img2coe.py $< > $@ |