Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

State Machine- State doesn't set logic as expected

The folowing code is designed to convert a 24 bit value in to 4x 6 bit values to transmit over a 6 conductor cable. At each state I define what my output clock should be by assinging a logic level to GeneratedClk. For some reason the output I get doesn't match what I expect. The clock only makes one cycle low and then back to high. I am sure there must be some easy explanation of how I don't understand variables vs. signals or something, but I would appreciate some advice.

entity DataTransmitter is

port (

ClkEnablePort : buffer std_logic;

DataRateClk : in std_logic;

SendData : in std_logic;

DataOutClk : out std_logic;

BusIn : in std_logic_vector(23 downto 0);

BusOut : buffer std_logic_vector(5 downto 0);

SendComplete : buffer std_logic;

Reset : in std_logic

);

end DataTransmitter;

architecture behavior of DataTransmitter is

type state is ( WaitingForData, Triggered,

SendBits0, LatchBits0, SendBits1, LatchBits1,

SendBits2, LatchBits2, SendBits3, LatchBits3,

SendFinish );

signal pr_state, nx_state : state;

signal GeneratedClk : std_logic;

signal Hold0 : std_logic_vector(5 downto 0); --Least Significant Bits

signal Hold1 : std_logic_vector(5 downto 0);

signal Hold2 : std_logic_vector(5 downto 0);

signal Hold3 : std_logic_vector(5 downto 0);

begin

---------- Advance States ----------

process( Reset, SendData, DataRateClk )

begin

if( Reset = '1') then

pr_state <= WaitingForData;

elsif ( SendData = '1' and pr_state = WaitingForData ) then

pr_state <= Triggered;

Hold0 <= BusIn(5 downto 0);

Hold1 <= BusIn(11 downto 6);

Hold2 <= BusIn(17 downto 12);

Hold3 <= BusIn(23 downto 18);

elsif ( rising_edge(DataRateClk) ) then

pr_state <= nx_state;

end if;

end process;

---------- Create Results for State Change ----------

process( pr_state )

variable SendThisData : std_logic_vector(5 downto 0);

variable GeneratedClk : std_logic;

begin

case pr_state is

when WaitingForData =>

nx_state <= WaitingForData;

GeneratedClk := '1';

SendComplete <= '0';

SendThisData := "000000";

when Triggered =>

nx_state <= SendBits0;

GeneratedClk := '1';

-----------------

when SendBits0 =>

nx_state <= LatchBits0;

GeneratedClk := '0';

SendThisData := Hold0;

when LatchBits0 =>

nx_state <= SendBits1;

GeneratedClk := '1';

SendThisData := Hold0;

-----------------

-----------------

when SendBits1 =>

nx_state <= LatchBits1;

GeneratedClk := '0';

SendThisData := Hold1;

when LatchBits1 =>

nx_state <= SendBits2;

GeneratedClk := '1';

SendThisData := Hold1;

-----------------

-----------------

when SendBits2 =>

nx_state <= LatchBits2;

GeneratedClk := '0';

SendThisData := Hold2;

when LatchBits2 =>

nx_state <= SendBits3;

GeneratedClk := '1';

SendThisData := Hold2;

-----------------

-----------------

when SendBits3 =>

nx_state <= LatchBits3;

GeneratedClk := '0';

SendThisData := Hold3;

when LatchBits3 =>

nx_state <= SendFinish;

GeneratedClk := '1';

SendThisData := Hold3;

-----------------

when SendFinish =>

GeneratedClk := '1';

SendThisData := "000000";

SendComplete <= '1';

when others =>

nx_state <= WaitingForData;

end case;

DataOutClk <= GeneratedClk;

BusOut <= SendThisData;

end process;

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Do not use buffer(obsolete).Your state transition is tied up to elsif...

    If you just want to serialise 24 bits into time muxed 6 bits then there might be easier ways of doing what you want e.g.

    
    signal count: integer range 0 to 3;
     
    process(reset,clk)
    begin
    if reset = '1' then
       count <= 0;
       input_en <= '0';
       BusOut <= (others => '0');
     elsif rising_edge(clk) then
     
       count <= count + 1;
     
       case count is
          when 0 => BusOut <= BusIn(17 downto 12); input_en <= '1';
          when 1 => BusOut<= BusIn(23 downto 18); input_en <= '0';
          when 2 => BusOut <= BusIn(5 downto 0); input_en <= '0';
          when 3 => BusOut <= BusIn(11 downto 6); input_en <= '0';
       end case;
    end process;

    the input_en pulse is to control the input rate(= input clk/4). It needs some care to synchronise the data request to the front module. I have assumed the request is raised at count 0, becomes high at count 1 and data is available soon at count 2. Such design is called pull data flow(not push)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for the tips.

    The state machine I had created was designed to latch-out the data on the SendBit(0-3) states and then send a rising edge (DataOutClk) on the LatchBits(0-3) states for the receiver to use to latch the data into the receiver. Unfortunately for some reason the DataOutClk doesn't toggle at every state as I would expect. It seems to skip the middle states. I believe that it enters the states but just doesn't toggle the DataOutClk by setting the GeneratedClk each time.