aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2023-03-13 18:26:54 +0100
committerlonkaars <loek@pipeframe.xyz>2023-03-13 18:26:54 +0100
commit74ec145c5e44a51789e9117b1ae93dfd7be24d86 (patch)
tree65861f837c708a8ff32ebcdfd389094492085ba9
parentb247b52429f2fc6aecd29539ec5afa0d47218147 (diff)
fix display upscaler (output working!)
-rw-r--r--basys3/basys3.srcs/ppu_dispctl.vhd96
-rw-r--r--basys3/basys3.srcs/ppu_dispctl_demo_top.vhd15
-rw-r--r--basys3/basys3.xpr68
-rwxr-xr-xtest/upscaler/img2coe.py (renamed from test/upscaler/bitmap-ball.py)4
-rw-r--r--test/upscaler/makefile4
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 $< > $@