LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY main IS PORT ( clk : IN STD_LOGIC; -- 80Mhz taster : IN STD_LOGIC; -- anfang des auslesens rst : IN STD_LOGIC; -- globaler reset enable : OUT STD_LOGIC; lad_in2 : OUT STD_LOGIC_VECTOR (3 DOWNTO 0); -- USB usb_RD_n : OUT STD_LOGIC; -- read (low active) usb_WR : INOUT STD_LOGIC; -- write usb_TXE_n : IN STD_LOGIC; -- transmit ready (low active) usb_SIWU : OUT STD_LOGIC; -- send immediate / wake up usb_DATA : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); -- usb datenbus -- Eprom eprom_clk : OUT STD_LOGIC; -- tackt für das eprom eprom_rst : OUT STD_LOGIC; -- eprom reset (low aktive) eprom_lframe : OUT STD_LOGIC; -- startsignal für ein frame(auslesevorgang) eprom_lad : INOUT STD_LOGIC_VECTOR (3 DOWNTO 0); -- bidirektionaler datenbus ERROR : OUT STD_LOGIC); -- 1 wenn der eprom den datenbus nicht übernimmt, sonst 0 END main; ARCHITECTURE Behavioral OF main IS -- 1.process SIGNAL enable_1mhz : STD_LOGIC := '0'; SIGNAL enable_count : INTEGER RANGE 79 DOWNTO 0 := 0; -- 2.process SIGNAL lad_in, lad_out : STD_LOGIC_VECTOR(3 DOWNTO 0) := x"0"; SIGNAL lad_control : STD_LOGIC := '0'; -- 3.process SIGNAL taster1 : STD_LOGIC; -- Flanke abfragen, um den Epromauslesevorgang zu starten SIGNAL state : INTEGER RANGE 39 DOWNTO 0 := 0; SIGNAL addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000"; SIGNAL data : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"00"; -- hier wird 1byte des eproms zwischen gespeichert CONSTANT addr_start : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"ffffffff"; CONSTANT addr_stopp : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"fff7ffff"; SIGNAL set_counter_to_1 : BOOLEAN; SIGNAL set_counter_to_0 : BOOLEAN; BEGIN PROCESS(clk) -- 1. enable signal erzeugen BEGIN IF rising_edge(clk) THEN IF enable_count = 0 THEN enable_1mhz <= '1'; enable_count <= 79; ELSE enable_1mhz <= '0'; enable_count <= enable_count - 1; END IF; END IF; END PROCESS; PROCESS(clk) -- 2. bidirektionale verbindung für lad BEGIN -- lad ist der eprom datenbus IF rising_edge(clk) THEN IF lad_control = '1' THEN eprom_lad <= lad_out; ELSE eprom_lad <= "ZZZZ"; lad_in <= eprom_lad; END IF; END IF; END PROCESS; --a counter PROCESS(clk) BEGIN IF rising_edge(clk) THEN IF rst = '1' THEN state <= 0; ELSE IF set_counter_to_1 THEN state <= 1; ELSIF set_counter_to_0 THEN state <= 0; ELSE state <= state + 1; END IF; END IF; END IF; END PROCESS; set_counter_to_1 <= ((state = 39) AND NOT (addr = x"fff7ffff")) OR (state = 28) AND NOT (lad_in = x"0"); set_counter_to_0 <= (state = 39) AND (addr = x"fff7ffff"); PROCESS(clk) -- auslesen des eproms, danach daten an usb schicken BEGIN IF rising_edge(clk) THEN usb_data <= data; IF rst = '1' THEN taster1 <= '1'; eprom_rst <= '0'; lad_control <= '1'; addr <= x"00000000"; eprom_lframe <= '1'; eprom_clk <= '0'; usb_WR <= '0'; ELSIF enable_1mhz = '1' THEN -- 1MHz taster1 <= taster; -- einsynchronisieren des tasters usb_WR <= '0'; usb_RD_n <= '1'; usb_SIWU <= '1'; -- lad wird bei fallender flanke geändert und bei steigender flanke ausgelesen -- pdf seite 12 ist die zeichnung CASE state IS -- State Maschine zur eprom ansteuerung WHEN 0 => IF taster1 = '0' AND taster = '1' THEN -- zum starten des auslesevorgang eprom_rst <= '1'; -- eprom nicht mehr resetten END IF; eprom_rst <= '0'; ERROR <= '0'; lad_control <= '1'; addr <= addr_start; eprom_lframe <= '1'; WHEN 1 => eprom_clk <= '0'; WHEN 3 => eprom_clk <= '0'; -- 1. clock, Start lad_control <= '1'; eprom_lframe <= '0'; lad_out <= x"0"; WHEN 5 => eprom_clk <= '0'; -- 2. clock, CYCTYOE + DIR eprom_lframe <= '1'; lad_out <= x"4"; -- "010x" für lesen WHEN 7 => eprom_clk <= '0'; -- 3. clock, Addresse 1 lad_out <= addr(31 DOWNTO 28); WHEN 9 => eprom_clk <= '0'; -- 4. clock, Addresse 2 lad_out <= addr(27 DOWNTO 24); WHEN 11 => eprom_clk <= '0'; -- 5. clock, Addresse 3 lad_out <= addr(23 DOWNTO 20); WHEN 13 => eprom_clk <= '0'; -- 6. clock, Addresse 4 lad_out <= addr(19 DOWNTO 16); WHEN 15 => eprom_clk <= '0'; -- 7. clock, Addresse 5 lad_out <= addr(15 DOWNTO 12); WHEN 17 => eprom_clk <= '0'; -- 8. clock, Addresse 6 lad_out <= addr(11 DOWNTO 8); WHEN 19 => eprom_clk <= '0'; -- 9. clock, Addresse 7 lad_out <= addr( 7 DOWNTO 4); WHEN 21 => eprom_clk <= '0'; -- 10. clock, Addresse 8 lad_out <= addr( 3 DOWNTO 0); WHEN 23 => eprom_clk <= '0'; -- 11. clock, Tar0 lad_out <= x"f"; -- signal für den eprom, das er übernimmt WHEN 25 => eprom_clk <= '0'; -- 12. clock, Tar1 lad_control <= '0'; -- umschalten lad datein eingang WHEN 27 => eprom_clk <= '0'; -- 13. clock, SYNC WHEN 28 => eprom_clk <= '1'; -- abfrage, ob der eprom den bus übernommen hat. IF NOT (lad_in = x"0") THEN ERROR <= '1'; -- wenn nein, von vorne END IF; WHEN 29 => eprom_clk <= '0'; -- 14. clock, DATA1 ERROR <= '0'; WHEN 30 => eprom_clk <= '1'; -- 1. hälfte des Bytes data(3 DOWNTO 0) <= lad_in; WHEN 31 => eprom_clk <= '0'; -- 15. clock, DATA2 WHEN 32 => eprom_clk <= '1'; -- 2. hälfte des Bytes data(7 DOWNTO 4) <= lad_in; WHEN 33 => eprom_clk <= '0'; -- 16. clock, Tar0 WHEN 35 => eprom_clk <= '0'; -- 17. clock, tar1 lad_control <= '1'; -- übername des busses lad_out <= x"F"; WHEN 37 => eprom_clk <= '0'; addr <= addr - 1; -- addresse einen runter WHEN 38 => IF usb_WR = '0' AND usb_TXE_n = '0' THEN -- write next byte if USB FIFO not full usb_WR <= '1'; END IF; WHEN OTHERS => eprom_clk <= '1'; END CASE; END IF; --enable END IF; --clk END PROCESS; enable <= enable_1mhz; lad_in2 <= lad_in; END Behavioral;