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.