aboutsummaryrefslogtreecommitdiff
path: root/basys3/basys3.srcs
diff options
context:
space:
mode:
Diffstat (limited to 'basys3/basys3.srcs')
-rw-r--r--basys3/basys3.srcs/ppu_dispctl.vhd96
-rw-r--r--basys3/basys3.srcs/ppu_dispctl_demo_top.vhd15
2 files changed, 53 insertions, 58 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,