Hallo zusammen, ich habe ein Spartan 3 Starter Kit und dort befindet sich eine SRAM drauf, ich will nun diesen SRAM ansteuern, um Daten abzuspeichern. Meine Frage: wo kann ich eine Schnittstelle/Lösung zu meinem Problem finden, bzw. was ist besonders zu beachten bei der Ansteuerung. Ich habe schon ein Programm in VHDL, aber er liest die falsche Daten aus, obwohl die Timing Simualtion korrekt aussieht. Ich hoffe mir kann jemand helfen. Danke, Gruß Tobias
Hallo Tobias, Hast du dir die Place & Route Simulation schon angeschaut? Kannst du deinen Code mal posten? Gruss Jörn
Ich habe mehrere Module, entity mc_connect_uart is Port ( clk : in std_logic; reset : in std_logic; ub1 : out std_logic; lb1 : out std_logic; ce1 : out std_logic; ce2 : out std_logic; we : out std_logic; oe : out std_logic; addr_count : out std_logic_vector(17 downto 0); serial_out : out std_logic; in_out : inout std_logic_vector(7 downto 0) ); end mc_connect_uart; architecture Behavioral of mc_connect_uart is signal connect : std_logic; signal baud_rate : std_logic; signal ground : std_logic; signal stop_read : std_logic; signal sram_uart : std_logic_vector(7 downto 0); signal en_s_u : std_logic; signal data_sig : std_logic_vector(7 downto 0); signal data_help : std_logic_vector(7 downto 0); signal enable : std_logic; signal addr_sig : std_logic_vector(17 downto 0); signal cv : std_logic; signal wen : std_logic; signal oen : std_logic; signal cen : std_logic; ------------------------------------------------------------------------ ------------------- -- DCM zum herunter teilen der 50 MHz auf 25 MHz COMPONENT clock_div PORT( RST_IN : IN std_logic; CLKIN_IN : IN std_logic; LOCKED_OUT : OUT std_logic; CLKDV_OUT : OUT std_logic; CLKIN_IBUFG_OUT : OUT std_logic; CLK0_OUT : OUT std_logic ); END COMPONENT; -- Komponente UART_Transmitter COMPONENT uart_tx PORT( data_in : IN std_logic_vector(7 downto 0); write_buffer : IN std_logic; reset_buffer : IN std_logic; en_16_x_baud : IN std_logic; clk : IN std_logic; serial_out : OUT std_logic; buffer_full : OUT std_logic; buffer_half_full : OUT std_logic ); END COMPONENT; ------------------------------------------------------------------------ ---------------------------- --Komponente Schreiben - Lesen COMPONENT write_read PORT( clock : IN std_logic; reset : IN std_logic; buffer_full : IN std_logic; ADDRESS : OUT std_logic_vector(17 downto 0); WE : OUT std_logic; OE : OUT std_logic; UB : OUT std_logic; LB : OUT std_logic; CE : OUT std_logic; enab_io : OUT std_logic ); END COMPONENT; -----Component data counter----------------------------------------------------------------- ---------------------------------- COMPONENT data_count PORT( clock : IN std_logic; reset : IN std_logic; enable : IN std_logic; data : OUT std_logic_vector(7 downto 0) ); END COMPONENT; -----component Input-output-buffer----------------------------------------------------- ------------------------------------------- component IOBUF port (I: in std_logic; T: in std_logic; O: out std_logic; IO: inout std_logic); end component; attribute box_type : string; attribute box_type of IOBUF : component is "black_box"; constant DATA_WIDTH : integer := 8; ------------------------------------------------------------------------ -------------------------------- begin -- Instanziate an input-output buffer U1 : for i in 0 to DATA_WIDTH - 1 generate U2: IOBUF port map ( I => data_sig(i), T => enable, O => sram_uart(i), IO => in_out(i) ); end generate; -- help_data <= data_sig; -- help_2 <= sram_uart; -----Instanziate the DCM (Digital Clock Manager)--------------------------------------------------------- ground <= '0'; Inst_clock_div: clock_div PORT MAP( RST_IN => ground, CLKIN_IN => clk, CLKDV_OUT => connect ); -- mit diesem Prozess erzeuge ich den entsprechenden Takt um das Uart mit der richtigen Frequenz arbeiten zu lassen baud_timer: process (connect) variable baud_count : integer range 0 to 2 := 0; begin if (connect = '1' and connect'event) then if (baud_count=1) then baud_count := 0; baud_rate <= '1'; else baud_count := baud_count + 1; baud_rate <= '0'; end if; end if; end process; -----Instanziate the microcontroller PicoBlaze----------------------------------------------------------- -- Inst_embedded_kcpsm3: embedded_kcpsm3 PORT MAP( -- out_port => out_sig, -- port_id => id_sig, -- in_port => bufferout_inport, -- interrupt => int_en, -- reset => reset, -- clk => connect -- ); -----Instanziate the modul uart which change 1 byte to 1 bit--------------------------------------------- Inst_uart_tx: uart_tx PORT MAP( data_in => sram_uart, write_buffer => en_s_u, reset_buffer => reset, en_16_x_baud => baud_rate, serial_out => serial_out, -- buffer_full => stop_read, buffer_half_full => stop_read, clk => connect ); -----Instanziate the modul that set the control signals and the address-------------------------------------------------- Inst_write_read: write_read PORT MAP( clock => connect, reset => reset, buffer_full => stop_read, ADDRESS => addr_count, WE => we, OE => oe, UB => ub1, LB => lb1, CE => ce1, enab_io => enable ); ce2 <= '1'; -----Instanziate the data_counter------------------------------------------------------------ ------------ Inst_data_count: data_count PORT MAP( clock => connect, reset => reset, enable => enable, data => data_sig ); ------change between writing data in sram and reading data from sram to uart----------------------------- set_enab_uart: process (connect, reset, enable) begin if (reset = '1') then en_s_u <= '0'; elsif (connect = '1' and connect'event) then if (enable = '1') then en_s_u <= '1'; elsif (enable = '0') then en_s_u <= '0'; end if; end if; end process; div_clock: process(connect, reset) begin if (reset = '1') then cv <= '0'; elsif (connect = '1' and connect'event) then cv <= not cv; end if; end process; -- delay_addr: process (cv, reset, addr_sig) -- begin -- if (reset = '1') then -- elsif (cv = '1' and cv'event) then data_sig <="01000000"; -- end if; -- end process; -- addr_count <= addr_sig; --data_help; -- delay_data: process (cv, reset, data_help, addr_sig, wen) -- begin -- if (reset = '1') then -- elsif (cv = '0' and cv'event) then --if (wen = '1') then -- if (wen = '0') then -- end if; -- end if; -- end process; -- we <= wen; -- oe <= oen; -- ce1 <= cen; end Behavioral;
entity data_count is Port ( clock : in std_logic; reset : in std_logic; enable : in std_logic; data : out std_logic_vector(7 downto 0)); end data_count; architecture Behavioral of data_count is signal counter : std_logic_vector(7 downto 0); signal cv : std_logic; constant cons : std_logic_vector(7 downto 0) := "10101010"; begin clock_div: process(clock, reset) begin if (reset = '1') then cv <= '0'; elsif (clock = '1' and clock'event) then cv <= not cv; end if; end process; data_count_proc: process (cv, reset) begin if (reset = '1') then counter <= (others => '0'); elsif (cv = '0' and cv'event) then counter <= counter + 1; data <= cons; --counter; end if; end process; end Behavioral;
entity write_read is Port (clock : in std_logic; reset : in std_logic; buffer_full : in std_logic; --data_mikrocontroller: in std_logic_vector (7 downto 0); ADDRESS : out std_logic_vector(17 downto 0); WE : out std_logic; OE : out std_logic; UB : out std_logic; LB : out std_logic; CE : out std_logic; enab_io : out std_logic); end write_read; architecture Behavioral of write_read is COMPONENT address_set PORT( clock : IN std_logic; reset : IN std_logic; buffer_full : IN std_logic; enab : OUT std_logic; addr_wr : OUT std_logic_vector(17 downto 0); addr_re : OUT std_logic_vector(17 downto 0) ); END COMPONENT; ------------------------------------------------------------------------ --------------------------------- COMPONENT control PORT( clock : IN std_logic; reset : IN std_logic; addr_wr : IN std_logic_vector(17 downto 0); addr_re : IN std_logic_vector(17 downto 0); enab : IN std_logic; buffer_full : IN std_logic; we : OUT std_logic; oe : OUT std_logic; ce : OUT std_logic; ub : OUT std_logic; lb : OUT std_logic; addr : OUT std_logic_vector(17 downto 0); enab_io : OUT std_logic ); END COMPONENT; ------------------------------------------------------------------------ --------------------------------- signal address_write : std_logic_vector(17 downto 0); signal address_read : std_logic_vector(17 downto 0); signal enable_signal : std_logic := '0'; ------------------------------------------------------------------------ --------------------------------- begin Inst_address_set: address_set PORT MAP( clock => clock, reset => reset, buffer_full => buffer_full, enab => enable_signal, addr_wr => address_write, addr_re => address_read ); ------------------------------------------------------------------------ --------------------------------- Inst_control: control PORT MAP( clock => clock, reset => reset, addr_wr => address_write, addr_re => address_read, enab => enable_signal, buffer_full => buffer_full, we => WE, oe => OE, ce => CE, ub => UB, lb => LB, addr => ADDRESS, enab_io => enab_io ); end Behavioral;
entity address_set is Port ( clock : in std_logic; reset : in std_logic; buffer_full : in std_logic; enab : out std_logic; addr_wr : out std_logic_vector(17 downto 0); addr_re : out std_logic_vector(17 downto 0)); end address_set; architecture Behavioral of address_set is signal enab_sig : std_logic; signal addr_wr_sig : std_logic_vector (17 downto 0); signal addr_re_sig : std_logic_vector (17 downto 0); signal cv : std_logic; begin clock_div: process(clock, reset) begin if (reset = '1') then cv <= '0'; elsif (clock = '1' and clock'event) then cv <= not cv; end if; end process; enable_process: process(cv, reset, addr_wr_sig, addr_re_sig) begin if (reset = '1') then enab_sig <= '0'; elsif (cv = '1' and cv'event) then if (addr_wr_sig = "000000000011111111") then enab_sig <= '1'; elsif (addr_re_sig = "000000000011111111") then enab_sig <= '0'; end if; enab <= enab_sig; end if; end process; addr_write: process(cv, reset, enab_sig) begin if (reset = '1') then addr_wr_sig <= (others => '0'); elsif (cv = '1' and cv'event) then if (enab_sig = '0') then addr_wr_sig <= addr_wr_sig + 1; if (addr_wr_sig = "000000000011111111") then addr_wr_sig <= (others => '0'); end if; end if; addr_wr <= addr_wr_sig; end if; end process; addr_read: process(cv, reset, enab_sig, buffer_full) begin if (reset = '1') then addr_re_sig <= (others => '0'); elsif (cv = '1' and cv'event) then if (buffer_full = '0') then if (enab_sig = '1') then addr_re_sig <= addr_re_sig + 1; if (addr_re_sig = "000000000011111111") then addr_re_sig <= (others => '0'); end if; end if; end if; addr_re <= addr_re_sig; end if; end process; end Behavioral;
entity control is Port ( clock : in std_logic; reset : in std_logic; addr_wr : in std_logic_vector(17 downto 0); addr_re : in std_logic_vector(17 downto 0); enab : in std_logic; buffer_full : in std_logic; we : out std_logic; oe : out std_logic; ce : out std_logic; ub : out std_logic; lb : out std_logic; addr : out std_logic_vector(17 downto 0); enab_io : out std_logic); end control; architecture Behavioral of control is signal we_sig : std_logic; signal cv : std_logic; begin clock_div: process(clock, reset) begin if (reset = '1') then cv <= '0'; elsif (clock = '1' and clock'event) then cv <= not cv; end if; end process; set_addr: process (cv, reset, enab, addr_wr, addr_re, buffer_full) begin if (reset = '1') then addr <= (others => '0'); elsif (cv = '1' and cv'event) then if (enab = '0') then addr <= addr_wr; enab_io <= '0'; elsif (buffer_full = '0') then addr <= addr_re; enab_io <= '1'; end if; end if; end process; set_control_signals: process (clock, reset, enab, buffer_full) begin if (reset = '1') then ce <= '0'; ub <= '1'; lb <= '0'; oe <= '1'; we <= '0'; elsif (clock = '1' and clock'event) then if (enab = '0') then ce <= '0'; ub <= '1'; lb <= '0'; oe <= '1'; we_sig <= not we_sig; elsif (buffer_full = '0') then ce <= '0'; ub <= '1'; lb <= '0'; oe <= '0'; we_sig <= '0'; end if; we <= not we_sig; end if; end process; end Behavioral;
Kannst du das ganze Projekt packen und als Datei hochladen? Gruss Jörn
Ja mache ich, das Prokjekt heißt beispiel.npl, ich habe jetzt nur die relevantesten dateien hinzugefügt, clock_div ist en DCM im Spartan - 3.
Der DCM wird bei mir nicht erkannt. Wird ein ? in der Projektverwaltung angezeigt.
Ein DCM gibt es, glaub ich nur beim Spartan - 3 Starter Kit. Bei z.B. Spartan II mußt du, glaub ich, DLL's nehmen, anstelle des DCM. Der DCM dient nur nur dazu den Systemtakt herunter zu teilen.
ich hab einen Spartan 3 Baustein eingestellt. Wird trotzdem nicht erkannt, s. Bild. Vielleicht stimmt mit der Instanzierung noch was nicht.
Hast du folgende Bibliotheken mit eingebunden? library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
Ja, mir fiel grad auf ich habe vergessen die xaw Datei mit zu geben.
Hallo Tobias, dein Design ist etwas unübersichtlich. Wenn ich dir einen Rat geben darf, nimmt das Top-Design (Oberste Hierarchieebene) nur um die einzelnen Komponenten zu instanzieren und diese zu verbinden. Lass dort die Prozesse weg. z.B. top | |-Uart | |-tx_makro | | |-Fifo | | |-tx | |-Baudraten_gen | |- Sram |- FSM Fördert die Übersichtlichkeit enorm und die einzelnen Komponenten lassen sich besser simulieren. Weiter ist mir aufgefallen, dass die funktionale Simulation scheitert (UART TX Leitung wird zu 'X'). Vermutlich liegt das an der Baudratengenerierung. Dein Zähler teilt deine 25 Mhz um Faktor 2 runter. Du musst aber einen Puls mit der 16fachen Frequenz deiner Baudrate generieren, s. Uart_Manual.pdf von Xilinx. Gruss Jörn
Hallo Jörn danke für dein Tip, ich werde es ausprobieren und es umbauen. Du meinst das ganze Problem liegt darin begründet? Oder könnte noch irgendwas fehlen in meiner Schaltung? Wie soll ich runter gehen mit den Hierarchieebenen? Soll ich für die Baudratengenerierung ein alleiniges Modul verwenden? Gruß Tobias
Hallo Jörn, ich habe es geändert und die tx leitung wird nicht mehr auf 'X' gesetzt. Aber ich habe immer noch das Problem, dass auf dem PC nicht die Werte angezeigt werden, die ich ürsprünglich in den SRAM abgespeichert habe. oran könnte das liegen? Gruß Tobias.
Kannst du dein aktuelle Design posten oder mir als Email schicken.
Hallo. Ich habe zu der SRAM-Problematik zwei Zwischenfragen. SRAM mit einem FPGA anzusteuern scheint ja zu funktionieren. Handelt es sich um asynchronen oder synchronen SRAM? Wie sieht es mit der Ansteuerung aus zwei verschiedenen Taktumgebungen aus, z.B. eine Taktumgebung zum Beschreiben des RAMs und eine andere zum Auslesen? Ist das sehr aufwändig in VHDL? Gruß, Marcus
Hallo Marcus, es ist ein asychrones RAM von ISSI. Du musst sicher stellen, dass die zwei Teilnehmer nicht gleichzeit auf das SRAM zugreifen. Für die deine Frage würde ich aber zu Dual Port RAMs greifen. Dies sind für so ausgelegt. Wieviel Speicher wird benötigt? Gruss Jörn
Moin Jörn, ja, Dual Port RAM, das habe ich mir auch schon überlegt. Dummerweise bin ich schon im Besitz von asynchronen SRAMs von Alliance Semi. (2x 1MBIT) inkl. Leiterplatine. Wir wollten ursprünglich die Sache in HandelC machen. Das klappt aber nicht so richtig. Meine 2. Frage in VHDL zu lösen sieht dann wohl eher schwierig aus? Gruß, Marcus
Hallo Jörn, ich hab mal mein überarbeitetes Projekt drangehängt. auf www.issi.com/pdf/61LV25616AL.pdf kannst du das Datenblatt finden zu meinem SRAM. Ich bin soweit, dass bei der Simualtion die ersten Werten nicht sauber zugewiesen werden. Wenn ich den FPGA prgrammiert habe, habe ich mir das ganze im HYper Terminal angeschaut und habe festgestellt, dass der SPeicher nur zwei Werte ausgibt. Ich hoffe du kannst mir helfen. Gruß Tobias P.S. die Baudratengenerierung funktioniert, d.h. dassist nicht das Problem.
Hallo noch eine Ergänzung. Nachdem ich kleinere Veränderungen an den Steuersignalen vorgenommen hatte, hatte ich einen festen Wert abspeichern und auslesen wollen, dies Funktioniert auch,d.h. ich kann einen Wert abspeichern und auslesen, aber wenn ein Zähler läuft funktioniert es nicht.
Welche der vier Möglichkeiten auf das SRAM zu schreiben, hast du benutzt ?
benutzt du auch die /WE /LB&/UB Signale? die bewegen sich in der Simulation überhaupt nicht. Lt. Datenblatt müssen sie für einen Schreibzugriff auch betätigt werden.
Naja LB und UB habe ich so verstanden, dass ise statisch sein können, das WE benutze ich beim Schreibvorgang und beim Lesevorgang kann es statischs sein. Mein Problem besteht ja darin, wenn ich einen festen Wert anlege, dann wird dieser abgespeichert und auch wieder ausgelesen. Wenn ich aber eine Folge von Werten verwende, z.B. einen Zähler bekomme ich am PC immer nur einen statischen Wert ausgelesen.
Hallo, ist denn keiner hier, der mein Programm mal auf eine Spartan-3 Board programmieren kann? Ich möchte mal wissen, ob mein Fehler an meiner Schaltung oder an meinem Board liegt. Ich habe versucht mir meinen Adresszähler auf einem Logikanalysator anzuschauen und festgestellt, dass die Adressen gar nicht gezählt werden, sondern beim Wert null bleiben. Ich hoffe mir kann jemand helfen. (P.S. meine VHDL Quellen befinden sich weiter oben) Gruß Tobias
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.