-- ************************************************* -- = == -- * | | /* -- ** ------- * | |/ * -- * *====| |====| | | | -- ** ------- * | |\ * -- * | | \* -- ELEKTRONIK = == -- ENTWICKLER -- AACHEN -- -- Adresse: -- F.Juergen Gensicke, Dipl.-Ing. (FH) -- Kirberichshofer Weg 31, D-52066 Aachen -- -- Tel.: +49 / 241 / 47580488 -- Mobil: +49 / 173 / 2931531 -- E-Mail: info@ee-ac.de -- ************************************************* -- Entwickelt fuer: -- -- Firmennamen -- -- Adresse: -- Firma -- Ansprechpartner -- Strasse, D-PLZ Ort -- -- Tel.: +49 / Vorwahl / Anschluss -- Mobil: +49 / Vorwahl / Anschluss -- E-Mail: E-Mail-Adresse -- ************************************************* -- Datei: processor.vhd -- Autor: F.Juergen Gensicke -- Datum: 19.04.2011 -- ************************************************* -- Beschreibung der Testbench: -- -- Simuliert einen 8-Bit Prcessor mit 8-Bit Adress- und Datenbus -- -- Revisionen: -- ============================= -- Aenderung am DATUM Version X: -- Autor: F.Juergen Gensicke -- Was?: -- Text mit Aenderungsbeschreibung -- ************************************************* -- Libraries: LIBRARY ieee; USE ieee.std_logic_1164.ALL; use IEEE.std_logic_unsigned.all; use ieee.std_logic_arith.all; USE std.textio.ALL; library altera; use altera.altera_primitives_components.all; -- ************************************************* entity processor is Port ( CLK : in std_logic; RST : in std_logic; Adressen : out std_logic_vector(7 downto 0); Daten : inout std_logic_vector(7 downto 0); nRD : out std_logic; nWR : out std_logic; nCS : out std_logic ); end processor; architecture arc_processor of processor is --Werte liegen als Dezimalzahlen zwischen 0 und 255 vor. Die Zahlenwerte sind immer 3-stellig (z.B. 002). TYPE myDATAARRAY IS ARRAY (integer range 255 DOWNTO 0) OF std_logic_vector(7 downto 0); signal RAMDATA : myDATAARRAY; signal DatenIn, DatenOut : std_logic_vector(7 downto 0); signal ADDRESS, DATA : std_logic_vector(7 downto 0); signal T, StartRAMTransfer : std_logic; signal help : integer; -- ########################################### -- Datenblatt 8-Bit-Prozessor Virtual-Proc8 -- ########################################### -- Bus access constant t_ADR_nCS0 : time := 0 ns; -- ADR to nCS constant t_nCS0_DAT : time := 10 ns; -- nCS=0 to DAT constant t_nCS1_ADR : time := 0 ns; -- nRD=1 to unvalid ADR -- Write Bus constant t_nCS0_nWR0 : time := 20 ns; -- nCS=0 to nWR=0 constant t_nCS0_nWR1 : time := 50 ns; -- min. time, nCS=0 to nWR=1 constant t_DAT_nWR1 : time := 10 ns; -- valide DAT until nWR=1 (Setup-Time) constant t_nWR1_DAT : time := 10 ns; -- nWR=1 to unvalide DAT (Hold-Time) constant t_nWR1_nCS1 : time := 10 ns; -- nWR=1 to nCS=1 -- Read Bus constant t_nCS0_nRD0 : time := 20 ns; -- nCS=0 to nRD=0 constant t_nCS0_nRD1 : time := 50 ns; -- min. time, nCS=0 to nRD=1 constant t_nRD0_DAT : time := 10 ns; -- nRD=0 to valide DAT constant t_DAT_nRD1 : time := 20 ns; -- valide DAT until nRD=1 (Setup-Time) constant t_nRD1_DAT : time := 10 ns; -- valide DAT after nRD=1 (Hold-Time) constant t_nRD1_nCS1 : time := 10 ns; -- nRD=1 to nCS=1 -- ########################################### -- Procedur Schreiben auf Bus -- ########################################### PROCEDURE BUS_WR ( signal RST : in std_logic; signal ADDRESS : in std_logic_vector(7 downto 0); signal DATA : in std_logic_vector(7 downto 0); signal T : out std_logic; signal Adressen : out std_logic_vector(7 downto 0); signal DatenOut : out std_logic_vector(7 downto 0); signal nRD : out std_logic; signal nWR : out std_logic; signal nCS : out std_logic ) IS BEGIN if (RST = '1') then T <= '0'; -- 0 = Input nRD <= '1'; nWR <= '1'; nCS <= '1'; DatenOut <= (others => '0'); Adressen <= (others => '0'); else nRD <= '1'; nWR <= '1'; nCS <= '1'; Adressen <= ADDRESS; wait for t_ADR_nCS0; nCS <= '0'; T <= '1'; wait for t_nCS0_DAT; DatenOut <= DATA; wait for t_nCS0_nWR0 - t_nCS0_DAT; nWR <= '0'; wait for t_DAT_nWR1; nWR <= '1'; wait for t_nWR1_DAT; DatenOut <= (others => '0'); wait for t_nWR1_nCS1; nCS <= '1'; T <= '0'; wait for t_nCS1_ADR; end if; END BUS_WR; -- ########################################### -- Procedur Lesen vom Bus -- ########################################### PROCEDURE BUS_RD ( signal RST : in std_logic; signal ADDRESS : in std_logic_vector(7 downto 0); signal DATA : out std_logic_vector(7 downto 0); signal T : out std_logic; signal Adressen : out std_logic_vector(7 downto 0); signal DatenIn : in std_logic_vector(7 downto 0); signal nRD : out std_logic; signal nWR : out std_logic; signal nCS : out std_logic ) IS BEGIN if (RST = '1') then T <= '0'; -- 0 = Input nRD <= '1'; nWR <= '1'; nCS <= '1'; Adressen <= (others => '0'); else nRD <= '1'; nWR <= '1'; nCS <= '1'; Adressen <= ADDRESS; wait for t_ADR_nCS0; nCS <= '0'; wait for t_nCS0_nRD0; nRD <= '0'; wait for t_nCS0_nRD1 - t_nCS0_nRD0; nRD <= '1'; DATA <= DatenIn; wait for t_nRD1_DAT; wait for t_nRD1_nCS1; nCS <= '1'; wait for t_nCS1_ADR; T <= '0'; end if; END BUS_RD; -- ########################################### -- Funktion HEXCHARACTER_to_INT -- ########################################### FUNCTION HEXCHARACTER_to_INT ( a : character ) RETURN integer IS variable b : integer; BEGIN case a is when '0' => b := 0; when '1' => b := 1; when '2' => b := 2; when '3' => b := 3; when '4' => b := 4; when '5' => b := 5; when '6' => b := 6; when '7' => b := 7; when '8' => b := 8; when '9' => b := 9; when others => NULL; end case; return b; end HEXCHARACTER_to_INT; BEGIN -- ########################################### -- Single-ended Bi-directional Buffer -- ########################################### IOBUF_Bit0 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(0), oe => T, o => DatenIn(0), io => Daten(0) ); IOBUF_Bit1 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(1), oe => T, o => DatenIn(1), io => Daten(1) ); IOBUF_Bit2 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(2), oe => T, o => DatenIn(2), io => Daten(2) ); IOBUF_Bit3 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(3), oe => T, o => DatenIn(3), io => Daten(3) ); IOBUF_Bit4 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(4), oe => T, o => DatenIn(4), io => Daten(4) ); IOBUF_Bit5 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(5), oe => T, o => DatenIn(5), io => Daten(5) ); IOBUF_Bit6 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(6), oe => T, o => DatenIn(6), io => Daten(6) ); IOBUF_Bit7 : ALT_IOBUF generic map ( IO_STANDARD => "Differential 1.2-V HSTL Class I", CURRENT_STRENGTH_NEW => "4mA", ENABLE_BUS_HOLD => "none", WEAK_PULL_UP_RESISTOR => "off", LOCATION => "IOBANK_3C" ) port map ( i => DatenOut(7), oe => T, o => DatenIn(7), io => Daten(7) ); -- ########################################### -- Concurrent Statemants -- ########################################### -- keine -- ########################################### -- Einlesen der Datei in einem virtuelle RAM-Block -- ########################################### inputfile_PROC : PROCESS FILE daten_ins_ram : TEXT open read_mode IS "d:\vhdl\fpga-ram-file-io\daten-ins-ram.txt"; variable rline : line; variable value : string(1 to 3); variable nEOL : boolean; variable I : integer range 0 to 255; BEGIN StartRAMTransfer <= '0'; -- Dunkelwerte einlesen wait until RST = '0'; I := 0; while not endfile(daten_ins_ram) loop readline(daten_ins_ram, rline); read(rline, value); help <= 100 * HEXCHARACTER_to_INT(value(1)); wait until clk = '1'; read(rline, value, nEOL); help <= help + 10 * HEXCHARACTER_to_INT(value(2)); wait until clk = '1'; read(rline, value, nEOL); help <= help + HEXCHARACTER_to_INT(value(3)); wait until clk = '1'; RAMDATA(I) <= conv_std_logic_vector(help, 8); wait until clk = '1'; I := I + 1; help <= 0; wait until clk = '1'; end loop; wait until clk = '1'; StartRAMTransfer <= '1'; wait; END PROCESS; -- ########################################### -- RAM-Speicherzugriff -- ########################################### RAM_ACCESS_PROC : PROCESS FILE daten_aus_ram : TEXT open write_mode is "d:\vhdl\fpga-ram-file-io\daten-aus-ram.txt"; variable N, M : integer range 0 to 255; variable adata : line; variable data_a : integer; begin -- Init M := 0; ADDRESS <= (others => '0'); DATA <= (others => '0'); wait until RST = '0' and StartRAMTransfer = '1'; GrandLoop : FOR M IN 0 to 255 LOOP -- Komplettes Paket ewig wiederholen. -- ############################################### -- Daten abspeichern -- ############################################### ADDRESS <= x"00"; RAMWrite : FOR N IN 0 to 255 LOOP DATA <= RAMDATA(N); wait until(CLK'Event and CLK = '1'); BUS_WR(RST, ADDRESS, DATA, T, Adressen, DatenOut, nRD, nWR, nCS); ADDRESS <= ADDRESS + 1; END LOOP RAMWrite; -- ############################################### -- Daten auslesen und abspeichern -- ############################################### ADDRESS <= x"00"; RAMRead : FOR N IN 0 to 255 LOOP wait until(CLK'Event and CLK = '1'); BUS_RD(RST, ADDRESS, DATA, T, Adressen, DatenIn, nRD, nWR, nCS); data_a := conv_integer(signed(DATA)); write(adata, data_a); writeline(daten_aus_ram, adata); ADDRESS <= ADDRESS + 1; END LOOP RAMRead; END LOOP GrandLoop; end process; end arc_processor;