diff options
Diffstat (limited to 'eindopdracht-progh2-vivado/eindopdracht-progh2-vivado.srcs/sources_1/pixeldata.vhd')
-rw-r--r-- | eindopdracht-progh2-vivado/eindopdracht-progh2-vivado.srcs/sources_1/pixeldata.vhd | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/eindopdracht-progh2-vivado/eindopdracht-progh2-vivado.srcs/sources_1/pixeldata.vhd b/eindopdracht-progh2-vivado/eindopdracht-progh2-vivado.srcs/sources_1/pixeldata.vhd new file mode 100644 index 0000000..28ef319 --- /dev/null +++ b/eindopdracht-progh2-vivado/eindopdracht-progh2-vivado.srcs/sources_1/pixeldata.vhd @@ -0,0 +1,105 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity pixeldata is + generic( + NOTE_HEAD_OFFSET : integer := 300; -- y coordinate of center of note head + NOTE_WIDTH : integer := 110; -- note image width + NOTE_HEIGHT : integer := 345; -- note image height + STAFF_SPACING : integer := 50; -- pitch between staff lines + STAFF_TOP_Y : integer := 220); -- y position of first staff line + port( + CLK: in std_logic; -- system clock + RESET: in std_logic; -- async reset + X, Y: in std_logic_vector(9 downto 0); -- pixel x/y + NOTE_IDX: in std_logic_vector(3 downto 0); + NOTE_WRONG: in std_logic; + RGB: out std_logic_vector(11 downto 0)); -- RGB output color +end pixeldata; + +architecture Behavioral of pixeldata is + component half_note_rom is port ( + clka : in std_logic; + addra : in std_logic_vector(15 downto 0); + douta : out std_logic_vector(0 downto 0)); + end component; + + signal iX, iY: unsigned (9 downto 0); -- pixel x/y + signal address : unsigned (15 downto 0); + signal data : std_logic_vector (0 downto 0); + signal NOTE_INDEX : integer; +begin + iX <= unsigned(X); + iY <= unsigned(Y); + NOTE_INDEX <= to_integer(unsigned(NOTE_IDX)); + + rom: component half_note_rom port map ( + clka => CLK, + addra => std_logic_vector (address), + douta => data + ); + + process (CLK) + variable note_x : integer; + variable note_y : integer; + variable note_upright : std_logic; + variable pixel_index : integer; + begin + if RESET = '1' then + RGB <= (others => '0'); + address <= (others => '0'); + note_x := 0; + note_y := 0; + note_upright := '1'; + + elsif rising_edge(CLK) then + -- calculate which notes are displayed upright + case NOTE_IDX is + -- f,g,a upright note + when "0000" | "0001" | "0010" => note_upright := '1'; + -- b,c,d,e,f hanging note + when others => note_upright := '0'; + end case; + + -- base note x position + note_x := 100; + -- base note y position (bottom staff y position, f) + note_y := STAFF_TOP_Y + 4 * STAFF_SPACING; + -- shift note y up by half a staff space for each increment of note_index + note_y := note_y - NOTE_INDEX * (STAFF_SPACING / 2); + + -- shift up note depending on if displayed upside down or not + case note_upright is + when '0' => note_y := note_y - NOTE_HEIGHT + NOTE_HEAD_OFFSET; + when '1' => note_y := note_y - NOTE_HEAD_OFFSET; + end case; + + pixel_index := to_integer(iX) - note_x + (to_integer(iY) - note_y) * NOTE_WIDTH; + if note_upright = '0' then + -- invert coordinates + pixel_index := NOTE_WIDTH * NOTE_HEIGHT - pixel_index; + end if; + address <= to_unsigned(pixel_index, address'length); + + -- white background by default + RGB <= x"fff"; + + -- black staff lines + if Y = STAFF_TOP_Y + 0 * STAFF_SPACING then RGB <= x"000"; end if; + if Y = STAFF_TOP_Y + 1 * STAFF_SPACING then RGB <= x"000"; end if; + if Y = STAFF_TOP_Y + 2 * STAFF_SPACING then RGB <= x"000"; end if; + if Y = STAFF_TOP_Y + 3 * STAFF_SPACING then RGB <= x"000"; end if; + if Y = STAFF_TOP_Y + 4 * STAFF_SPACING then RGB <= x"000"; end if; + + -- display note if in correct opsition + if (iX >= note_x) and (iX < (note_x + NOTE_WIDTH)) and + (iY >= note_y) and (iY < (note_y + NOTE_HEIGHT)) then + if data(0) = '0' then + RGB <= x"f00" when NOTE_WRONG = '1' else x"000"; + end if; + end if; + end if; + end process; +end Behavioral; |