Hallo Leute, hab ne State Machine nach Moore mit drei Prozessen geschrieben. Die States arbeiten Synchron. Ich will damit bei bestimmten Zuständen verschieden Werte einem Signal zuweisen. Sollte also eigentlich kein Problem sein. Die Folgenden States gibt es vom Prinzip: Idle state -> keine änderung des Signals. (null;) State A -> MySignal(15 downto 0) <= x"AAAA"; State B -> MySignal(15 downto 0) <= x"BBBB"; (Ist klar dass es kein richtiger VHDL-Code ist!) Problem: Solange ich mich im State A befinde ist MySignal = "AAAA" und im State B = "BBBB". So wie es sein soll. Geht er aber wieder in den Idle State ist mein Signal plötzlich wieder auf "0000". Ich verstehe einfach nicht warum. Es gibt keine weiter Signalzuweisung im gesamten Code! Habe jetzt auch schon porbiert im Idle State oder vor der case-Abfrage MySignal <= MySignal; Hilft aber auch nicht. An was könnte es liegen? Hoffe ihr könnt mir weiterhelfen.
Okay, dann ist hier mal der Code. Ist halt schon recht viel. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity fb_Top_Module is port( --RSTn : in std_logic; -- low activ clk : in std_logic; -- Clock 50Mhz from external Quarz clk_60MHz_out: out std_logic; -- System Clock 60Mhz from DCM Button1 : in std_logic; -- init Button2 : in std_logic; -- send next Button3 : in std_logic; -- get next byte Switch : in std_logic_vector(4 downto 1); -- RS232-PC anschluss zum debuggen RS232_sRX : in std_logic; RS232_sTX : out std_logic; -- Moduleinterface anschlüsse nach außen Module_Conect : in std_logic; MI1_UA_sRX : in std_logic; MI1_UA_sTX : out std_logic; MI1_UB_sRX : in std_logic; MI1_UB_sTX : out std_logic; MI1_UA_DataReceive_o : out std_logic_vector(7 downto 0); MI1_DataSend_o : out std_logic_vector(15 downto 0); MI2_UA_sRX : in std_logic; MI2_UA_sTX : out std_logic; MI2_UB_sRX : in std_logic; MI2_UB_sTX : out std_logic; SaveData2 : out std_logic_vector(15 downto 0); DebugSig : out std_logic_vector(7 downto 0) ); end fb_Top_Module; architecture Behavioral of fb_Top_Module is signal clk_60MHz : std_logic; signal RSTn : std_logic; -- ------------------------------------------------------------- -- Moduleinterfaces & RS232 signal rst : std_logic; signal Uart_Command : std_logic_vector(2 downto 0):="000"; -- RS232 signal RS232_Uart_Command : std_logic_vector(2 downto 0):="000"; signal RS232_IRQ : std_logic_vector(1 downto 0); signal RS232_DataSend : std_logic_vector(15 downto 0); signal RS232_DataReceive : std_logic_vector(15 downto 0); signal RS232_rdy : std_logic; -- Moduleinterface 1 signal MI1_IRQ : std_logic_vector(1 downto 0); signal MI1_DataSend : std_logic_vector(15 downto 0); signal iMI1_DataSend : std_logic_vector(15 downto 0); signal MI1_DataReceive : std_logic_vector(15 downto 0); signal MI1_rdy : std_logic; -- Moduleinterface 2 signal MI2_IRQ : std_logic_vector(1 downto 0); signal MI2_DataSend : std_logic_vector(15 downto 0); signal MI2_DataReceive : std_logic_vector(15 downto 0); signal Zeichen : std_logic_vector(7 downto 0); signal SaveData : std_logic_vector(15 downto 0); -- ------------------------------------------------------------- -- Haupt FSM type state_type is (TopFSMrst, TopFSM1, TopFSM2, TopFSM3, TopFSM4, TopFSM5, TopFSM5a, TopFSM5b, TopFSM5c, TopFSM6, TopFSM7, TopFSM8, TopFSM9, TopFSM10); signal state_TopFSM, next_state_TopFSM : state_type; component DCM_60MHz is port( CLKIN_IN : in std_logic; CLKFX_OUT : out std_logic; CLKIN_IBUFG_OUT : out std_logic; CLK0_OUT : out std_logic ); end component; component Uart_ctrl is generic (Divisor : std_logic_vector(15 downto 0):= x"0001"); port( -- Module Interface anschlüsse rst : in std_logic; -- high activ clk : in std_logic; Uart_Command : in std_logic_vector(2 downto 0); rdy : out std_logic; TXRDYn : out std_logic; RXRDYn : out std_logic; IRQ : out std_logic_vector(1 downto 0); DataReceive : out std_logic_vector(15 downto 0); DataSend : in std_logic_vector(15 downto 0); -- Module Interface anschlüsse nach außen UA_sRX : in std_logic; UA_sTX : out std_logic; UB_sRX : in std_logic; UB_sTX : out std_logic; DebugSig : out std_logic_vector(7 downto 0) ); end component; begin clk_60MHz_out <= clk_60MHz; -- System Clock 60Mhz from DCM RSTn <= Switch(1); rst <= not RSTn; --MI1_DataSend(15 downto 0) <= x"2ACC"; MI1_UA_DataReceive_o <= MI1_DataReceive(7 downto 0); MI1_DataSend_o <= MI1_DataSend; -- -------------------------------------------------------------------- -- Haupt FSM zur erzeugung der Kommandos durch Tastendruck oder IRQ SYNC_PROC: process (clk_60MHz) begin if ( clk_60MHz'event and clk_60MHz = '1') then if (RSTn = '0') then state_TopFSM <= TopFSMrst; else state_TopFSM <= next_state_TopFSM; -- MI1_DataSend <= MI1_DataSend; end if; end if; end process; --MOORE State-Machine - Outputs based on state only OUTPUT_DECODE: process (state_TopFSM) begin Uart_Command <= "000"; RS232_Uart_Command <= "000"; MI1_DataReceive <= MI1_DataReceive; case (state_TopFSM) is when TopFSMrst => Uart_Command <= "000"; RS232_Uart_Command <= "000"; RS232_DataSend(15 downto 8) <= (others=>'0'); RS232_DataSend(7 downto 0) <= (others=>'0'); SaveData <= (others=>'0'); --Idle when TopFSM1 => null; --Init when TopFSM2 => Uart_Command <= "010"; RS232_Uart_Command <= "010"; --Send to MI1 when TopFSM3 => MI1_DataSend <= x"2ACC";--x"01e1"; when TopFSM4 => Uart_Command <= "100"; when TopFSM5 => null; when TopFSM5a => MI1_DataSend <= x"CC0A";--x"0001"; when TopFSM5b => null; when TopFSM5c => Uart_Command <= "100"; --Get next byte from MI1 and send to RS232 when TopFSM6 => Uart_Command <= "101"; SaveData <= MI1_DataReceive; when TopFSM7 => null; when TopFSM8 => RS232_Uart_Command <= "100"; RS232_DataSend(7 downto 0) <= x"46";--SaveData(15 downto 8); when TopFSM9 => null; when TopFSM10 => RS232_Uart_Command <= "100"; RS232_DataSend(7 downto 0) <= x"42";--SaveData( 7 downto 0); end case; end process; NEXT_STATE_DECODE: process (state_TopFSM, Button1, Button2, Button3, MI1_IRQ, RS232_rdy, MI1_rdy) begin next_state_TopFSM <= state_TopFSM; case (state_TopFSM) is when TopFSMrst => next_state_TopFSM <= TopFSM1; when TopFSM1 => -- Idle if Button1 = '1' then next_state_TopFSM <= TopFSM2; elsif Button2 = '1' then next_state_TopFSM <= TopFSM3; elsif Button3 = '1' then next_state_TopFSM <= TopFSM6; end if; -- Button1 when TopFSM2 => -- Init next_state_TopFSM <= TopFSM1; -- Button2 when TopFSM3 => -- release button wait if Button2 = '0' then next_state_TopFSM <= TopFSM4; else next_state_TopFSM <= state_TopFSM; end if; when TopFSM4 => next_state_TopFSM <= TopFSM5; when TopFSM5 => if MI1_rdy = '1' then next_state_TopFSM <= TopFSM1; else next_state_TopFSM <= state_TopFSM; end if; when TopFSM5a => next_state_TopFSM <= TopFSM5b; when TopFSM5b => next_state_TopFSM <= TopFSM5c; when TopFSM5c => next_state_TopFSM <= TopFSM1; -- Button3 when TopFSM6 => -- Read MI1 and wait for MI1_IRQ = 0; -- Status kann evtl. weg/ übersprungen werden next_state_TopFSM <= TopFSM7; when TopFSM7 => -- get next byte from MI1 -- if MI1_IRQ = "00" then next_state_TopFSM <= TopFSM8; -- end if; when TopFSM8 => -- send higher byte to RS232 next_state_TopFSM <= TopFSM9; when TopFSM9 => -- wait if RS232_rdy = '1' then next_state_TopFSM <= TopFSM10; end if; when TopFSM10=> -- send lower byte to RS232 next_state_TopFSM <= TopFSM1; end case; end process; DCM60 : DCM_60MHz port map( CLKIN_IN => clk, CLKFX_OUT => clk_60MHz, -- System Clock 60Mhz from DCM CLKIN_IBUFG_OUT=> open, CLK0_OUT => open ); RS232 : Uart_Ctrl generic map (divisor => x"0021") port map( rst => rst, clk => clk_60MHz, Uart_Command => RS232_Uart_Command, rdy => RS232_rdy, TXRDYn => open, RXRDYn => open, IRQ => RS232_IRQ, DataReceive => RS232_DataReceive, DataSend => RS232_DataSend, UA_sRX => RS232_sRX, UA_sTX => RS232_sTX, UB_sRX => '0', UB_sTX => open, DebugSig => open ); ModulInterface1 : Uart_Ctrl generic map (divisor => x"0001") port map( rst => rst, clk => clk_60MHz, Uart_Command => Uart_Command, rdy => MI1_rdy, TXRDYn => open, RXRDYn => open, IRQ => MI1_IRQ, DataReceive => MI1_DataReceive, DataSend => MI1_DataSend, UA_sRX => MI1_UA_sRX, UA_sTX => MI1_UA_sTX, UB_sRX => MI1_UB_sRX, UB_sTX => MI1_UB_sTX, DebugSig => DebugSig ); end Behavioral;
@ Flo B. (mcolf)
>Okay, dann ist hier mal der Code. Ist halt schon recht viel.
Aber lesen kannst du?
"Wichtige Regeln - erst lesen, dann posten!"
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Dein Problem ist eigentlich klar. Durch die von mir mehrfach als
unsinnig ausgewiesene 2/3 Prozessmethode baut man sich viel schneller
Latches in die Schaltung (-> SCHLECHT!) und muss ich um JEDE Zuweisung
selber kümmern, vor allem die impliziten, wenn KEIN Datenwechsel
erfolgen soll.
Schreib deine State Machine zumindest in einen Prozess, die Dekodierung
zusätzlicher Ausgänge KANN man in einem anderen machen. Aber das sind
REINE kombinatorische Signale, KEINE Speicher. Die muss man dann direkt
in die FSM packen. Ist auch übersichtlicher.
MFG
Falk
Es klingt so als willst du einen latch einbauen, sodass bei den Zustandsübergängen A->IDLE, B->IDLE Signal den alten Wert beibehält. Die Umsetzung ist aber Kacke. Mach aus den Ausgangssignale Register. ala
1 | signal val_next, val_reg : bit_vector(3 downto 0); |
2 | |
3 | update: process |
4 | begin
|
5 | wait until rising_edge(clk); |
6 | state_reg <= state_next; |
7 | val_reg <= val_next; |
8 | end process; |
9 | |
10 | ausgabe: process(state_reg) |
11 | begin
|
12 | val_next <= val_reg; |
13 | state_next <= state_reg; |
14 | case state_reg is |
15 | when IDLE => null; -- im grunde tut er das was in Zeile 1,2 steht |
16 | when A => val_next <= "aaaa"; |
17 | when B => val_next <= "bbbb"; |
18 | end case; |
19 | end process; |
20 | |
21 | state_transiotion: process |
22 | begin
|
23 | -- up to you ;)
|
24 | end process; |
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.