+ Post New Thread
Page 1 of 2 1 2 LastLast
Results 1 to 20 of 25
  1. #1
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Finite State Machine working in simulation, but not working on actual FPGA board

    hi guys,

    i've written the following code as a control unit for my project (FPGA implementation of a functional microcontroller).

    the code is working in simulation using modelsim.

    also it is synthesised using xilinx.

    but when i program it on an actual FPGA(spatan 3) i'm not getting correct working.

    the part which is not working is when i give the IN instruction.

    for entering a data the in_s state will continue until the enter pin has a low to high transition. (refer lines 104 to 110 of program)

    but it is not working.

    the in_s state is continuing infinitely.

    please help me with this.

    Thanks in advance.

    Code:
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity mealy is
    port (clk : in std_logic;
          reset : in std_logic;
          enter : in std_logic;
          input:in std_logic_vector(3 downto 0);
          output:out std_logic_vector(3 downto 0);
          pc_enable: out std_logic;
          alu_enable: out std_logic;
          rom_enable: out std_logic;
          reg_enable: out std_logic;
          ir_enable: out std_logic;
          load_a:out std_logic_vector(2 downto 0);
          load_b:out std_logic_vector(2 downto 0);
          pc_reset:out std_logic;
          a_zero_status:in std_logic;
          sel: out std_logic
      );
    end mealy;
    
    architecture behavioral of mealy is
    
    type state_type is (fetch,decode,add_s,sub_s,mov_ab_s,and_s,or_s,mov_ba_s,in_s,out_s,jmp_s,jnz_s,jz_s,inc_s,dec_s,halt_s,rab,wa,wb,ra,nop_s);  --type of state machine.
    signal current_s,next_s: state_type;  --current and next state declaration.
    signal enter_r:std_logic;
    
    begin
    
    process (clk,reset)
    begin
     if (reset='1') then
      current_s <= fetch;  --default state on reset.
      pc_reset<='1';
    elsif (rising_edge(clk)) then
      current_s <= next_s;   --state change.
      pc_reset<='0';
    end if;
    end process;
    
    --state machine process.
    process (current_s,enter,input,a_zero_status)
    begin
      case current_s is
        
        when fetch =>        --when current state is "fetch"
        next_s <= decode;
           
        when decode =>       --when current state is "decode"
        if(input ="0000") then
        next_s <= rab;
        elsif(input ="0001") then
        next_s <= rab;
        elsif(input ="0010") then
        next_s <= rab;
        elsif(input ="0011") then
        next_s <= rab;
        elsif(input ="0100") then
        next_s <= rab;
        elsif(input ="0101") then
        next_s <= ra;
        elsif(input ="0110") then
        next_s <= in_s;
        elsif(input ="0111") then
        next_s <= ra;
        elsif(input ="1000") then
        next_s <= jmp_s;
        elsif(input ="1001") then
        next_s <= jnz_s;
        elsif(input ="1010") then
        next_s <= jz_s;
        elsif(input ="1011") then
        next_s <= nop_s;
        elsif(input ="1100") then
        next_s <= rab;
        elsif(input ="1101") then
        next_s <= rab;
        elsif(input ="1111") then
        next_s <= halt_s;
        
        else
        next_s<=decode;
        end if;
    
    
        when add_s =>         --when current state is "add_s"
        next_s <= wa;
        
        when sub_s =>         --when current state is "sub_s"
        next_s <= wa;
        
        when mov_ab_s =>         --when current state is "mov_ab_s"
        next_s <= wa;
        
        when and_s =>         --when current state is "and_s"
        next_s <= wa;
        
        when or_s =>         --when current state is "or_s"
        next_s <= wa;
        
        when mov_ba_s =>         --when current state is "mov_ba_s"
        next_s <= wb;
        
        when in_s =>         --when current state is "in_s"
        enter_r<=enter;
        if(enter_r='0' and enter='1') then
        next_s <= fetch;
        else
        next_s <= in_s;
        end if;
        
        when out_s =>         --when current state is "out_s"
        next_s <= fetch;
        
        when jmp_s =>         --when current state is "jmp_s"
        next_s <= fetch;
        
        when jnz_s =>         --when current state is "jnz_s"
        next_s <= fetch;
        
        when jz_s =>         --when current state is "jz_s"
        next_s <= fetch;
        
        when nop_s =>         --when current state is "nop_s"
        next_s <= fetch;
        
        when inc_s =>         --when current state is "inc_s"
        next_s <= wa;
        
        when dec_s =>         --when current state is "dec_s"
        next_s <= wa;
        
        when halt_s =>         --when current state is "halt_s"
        next_s <= halt_s;
    
        when rab =>       --when current state is "rab"
        if(input ="0000") then
        next_s <= add_s;
        elsif(input ="0001") then
        next_s <= sub_s;
        elsif(input ="0010") then
        next_s <= mov_ab_s;
        elsif(input ="0011") then
        next_s <= and_s;
        elsif(input ="0100") then
        next_s <= or_s;
        elsif(input ="1100") then
        next_s <= inc_s;
        elsif(input ="1101") then
        next_s <= dec_s;
        
        end if;
        
        when wa =>         --when current state is "wa"
        next_s <= fetch;
        
        when wb =>         --when current state is "wb"
        next_s <= fetch;
        
        when ra =>         --when current state is "wb"
        if(input ="0101") then
        next_s <= mov_ba_s;
        elsif(input ="0111") then
        next_s <= out_s;
        end if;
        
             
    end case;
    end process;
        
        output_logic:process(current_s)
        begin
            case current_s is
                
            when fetch=>
                    pc_enable<='1';
                    alu_enable<='0';
                    rom_enable<='1';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    
            when decode=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='1';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    
              when add_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="0000";
                    
              when sub_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="0001";
                    
             when mov_ab_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="110";
                    load_b<="110";
                    sel<='0';
                    output<="0010";
                    
            when and_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="0011";
                    
            when or_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="0100";
                    
            when mov_ba_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="0101";
                    
            when in_s=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='1';
                    ir_enable<='0';
                    load_a<="110";
                    load_b<="UUU";
                    sel<='1'; 
                    output<="0110";
                    
            when out_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='0';
                    output<="0111";
                    
            when jmp_s=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='0';
                    output<="1000";
                    
            when jnz_s=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='0';
                    output<="1001";
                    
            when jz_s=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='0';
                    output<="1010";
                    
            when nop_s=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='0';
                    output<="1011";
                    
            when inc_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="1100";
                    
            when dec_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='0';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="UUU";
                    sel<='U';
                    output<="1101";
                    
            when halt_s=>
                    pc_enable<='0';
                    alu_enable<='1';
                    rom_enable<='0';
                    reg_enable<='1';
                    ir_enable<='0';
                    load_a<="101";
                    load_b<="UUU";
                    sel<='U';
                    output<="0111";
                    
             when wa=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='1';
                    ir_enable<='0';
                    load_a<="110";
                    load_b<="UUU";
                    sel<='0';
                    
              when wb=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='1';
                    ir_enable<='0';
                    load_a<="UUU";
                    load_b<="110";
                    sel<='U';
                    
              when rab=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='1';
                    ir_enable<='0';
                    load_a<="101";
                    load_b<="101";
                    sel<='0';
                    
            when ra=>
                    pc_enable<='0';
                    alu_enable<='0';
                    rom_enable<='0';
                    reg_enable<='1';
                    ir_enable<='0';
                    load_a<="101";
                    load_b<="UUU";
                    sel<='U';
                                        
      end case;
    end process;
    
    end behavioral;
    Last edited by goodpranoy; 10th January 2014 at 17:13.

  2. #2
    Advanced Member level 5
    Points: 37,734, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,842
    Helped
    2011 / 2011
    Points
    37,734
    Level
    47

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Im very surprised this compiled in XIlinx. You can only use a rising_edge() function on a clock - and then you cannot use it 3 times in a process. It will work in simulation because you can write any code you want for simulation, but if it doesnt follow the correct templates for synthesis it wont synthesis. So you MUST remove the rising_edge() function out of the async part of the state machine. You're going to have to do the detection manually, register the "enter" signal and then compare the registered version to the input.

    Did you check the RTL diagram? did it mach the logic you expected? I expect it didnt, or you didnt even look at it?


    1 members found this post helpful.

  3. #3
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Quote Originally Posted by TrickyDicky View Post
    Im very surprised this compiled in XIlinx. You can only use a rising_edge() function on a clock - and then you cannot use it 3 times in a process. It will work in simulation because you can write any code you want for simulation, but if it doesnt follow the correct templates for synthesis it wont synthesis. So you MUST remove the rising_edge() function out of the async part of the state machine. You're going to have to do the detection manually, register the "enter" signal and then compare the registered version to the input.

    Did you check the RTL diagram? did it mach the logic you expected? I expect it didnt, or you didnt even look at it?

    sir,
    first of all i am sorry, i posted another code .

    i have edited my program and posted it in the previous post.

    in this program i have only used rising edge detection once in each process.



  4. #4
    Advanced Member level 5
    Points: 37,734, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,842
    Helped
    2011 / 2011
    Points
    37,734
    Level
    47

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    The problem is you've created a latch with the enter_r signal - not a register. You need to put enter_r in a clocked process (you could just stick it in the current_s process). It can be assigned on every clock edge.


    1 members found this post helpful.

    •   AltAdvertisement

        
       

  5. #5
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    sir did you mean like this??

    Code:
    process (clk,reset)
    begin
     if (reset='1') then
      current_s <= fetch;  --default state on reset.
      pc_reset<='1';
    elsif (rising_edge(clk)) then
      current_s <= next_s;   --state change.
      
      enter_r<=enter;
      
      pc_reset<='0';
    end if;
    end process;



  6. #6
    Advanced Member level 5
    Points: 37,734, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,842
    Helped
    2011 / 2011
    Points
    37,734
    Level
    47

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Yes, but make sure you reset it as well, otherwise you're emulating a sync enable with the reset. If you dont want an async reset on it, put it in it's own process.


    1 members found this post helpful.

  7. #7
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Quote Originally Posted by TrickyDicky View Post
    Yes, but make sure you reset it as well, otherwise you're emulating a sync enable with the reset.
    sir,

    i am new to VHDL

    so i didn't understand your reply completely.

    could you please explain it with a code?



  8. #8
    Advanced Member level 3
    Points: 5,700, Level: 17

    Join Date
    Jul 2010
    Posts
    923
    Helped
    294 / 294
    Points
    5,700
    Level
    17

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    one example would be:
    Code:
    process (clk, rst) is
    begin
      if rising_edge(clk) then
        enter_r <= enter;
        state <= next_state;
      end if;
      if rst = '1' then
        state <= fetch; -- this is also bad practice, see more later
        --enter_r <= enter; -- this is optional as enter_r is not used until several cycles after reset.
      end if;
    The state machine should not have an async reset unless you ensure it is deasserted synchronously. This is because the reset signal may not reach all bits of the state registers at exactly the same time. In your case, the first cycle after reset is to go to "decode". if "fetch" is state "0001" and "decode" is "0010", then you could end up in states "0000" or "0011" if the reset arrives at the lsb of the state early or late. This also applies to "enter", which might be an async input (you'll have to tell us).

    For the combinatorial logic, you have to have the signal defined for all code paths. it is common to do:
    Code:
    process ( signals that you use here ) is
    begin
      next_state <= state;
      case state is
      when SOME_STATE =>
        if action = '1' then
          next_state <= OTHER_STATE;
        end if;
       ...
      end case;
    end process;
    Now if you have action='0' and state = SOME_STATE, there will be logic setting next_state to SOME_STATE.



  9. #9
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Quote Originally Posted by permute View Post
    one example would be:
    This also applies to "enter", which might be an async input (you'll have to tell us).
    yes it is an async input.(a dip switch or a push button).


    how can i synchronise the enter input with the clock?



    •   AltAdvertisement

        
       

  10. #10
    Full Member level 3
    Points: 1,650, Level: 9

    Join Date
    Jan 2012
    Posts
    155
    Helped
    58 / 58
    Points
    1,650
    Level
    9

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Simple -> sample it with a clock (DFF for eg)

    or just

    --state machine process.
    process (current_s,enter,input,a_zero_status) change to process(CLK) and add if rising_edge(CLK) then all this FSM cases



    •   AltAdvertisement

        
       

  11. #11
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    did the sampling using a DFF.

    but now there is a different problem.

    if my program is

    in a
    mov b,a
    in a
    add a,b
    halt.

    i need the two in statements to read two different values.
    but now when i give a '1' with dip switch then both my in instructions work simultaneously and i get the same input at both a and b registers.

    my project guide said that it may be due to some sparking in the switch which causes multiple rising edges and as the FPGA is very fast both the instructions work at the same time.

    please help me with this.

    why is this happening?

    is there any problem with my code?

    pls suggest a method to overcome this.

    thanks in advance.



  12. #12
    Full Member level 3
    Points: 1,650, Level: 9

    Join Date
    Jan 2012
    Posts
    155
    Helped
    58 / 58
    Points
    1,650
    Level
    9

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    If your FPGA clock is like 50 Mhz then there is no way that you will proceed this instructions with a dipswitch cause u got only 20 ns to do it :D

    I made a similar project few years ago for uni and to show that it is HW working i used BCD to show acc value and i slowed my internal clock 10 milins time to have time to change dipswitch.

    So u can just add rolling over counter to like 50_000_000 (for 50Mhz clok =1s) that will generate CE for your fpga-microcontroller clock



  13. #13
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Quote Originally Posted by axcdd View Post
    If your FPGA clock is like 50 Mhz then there is no way that you will proceed this instructions with a dipswitch cause u got only 20 ns to do it :D

    I made a similar project few years ago for uni and to show that it is HW working i used BCD to show acc value and i slowed my internal clock 10 milins time to have time to change dipswitch.

    So u can just add rolling over counter to like 50_000_000 (for 50Mhz clok =1s) that will generate CE for your fpga-microcontroller clock
    so what clock period should i divide my FPGA clock to?



  14. #14
    Full Member level 3
    Points: 1,650, Level: 9

    Join Date
    Jan 2012
    Posts
    155
    Helped
    58 / 58
    Points
    1,650
    Level
    9

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    I think 1 second ++ is enought to change dip, it all depands on your reflex ;]
    -----------------------------------------------------------------------------------------------------------
    now i read what this dipswitch does. U can just do what TrickyDicky says.
    Last edited by axcdd; 16th January 2014 at 15:00.


    1 members found this post helpful.

  15. #15
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    1 second period?

    so then how will the sparking problem be solved?



  16. #16
    Advanced Member level 5
    Points: 37,734, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,842
    Helped
    2011 / 2011
    Points
    37,734
    Level
    47

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Instead of checking for the switch to be '1', why not just detect a change from '0' -> '1'?



  17. #17
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Quote Originally Posted by TrickyDicky View Post
    Instead of checking for the switch to be '1', why not just detect a change from '0' -> '1'?
    this FSM is later portmapped with a 2 stage DFF to detect the rising edge.

    in that also the spark in switch causes multiple rising edges :(



  18. #18
    Advanced Member level 5
    Points: 37,734, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,842
    Helped
    2011 / 2011
    Points
    37,734
    Level
    47

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Its probably no spark - have you debounced the swtich?


    1 members found this post helpful.

  19. #19
    Junior Member level 3
    Points: 143, Level: 1

    Join Date
    Dec 2013
    Posts
    29
    Helped
    0 / 0
    Points
    143
    Level
    1

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    Quote Originally Posted by TrickyDicky View Post
    Its probably no spark - have you debounced the swtich?
    nope. :)

    after what time will the switch reach a stable state?


    BTW debouncing only checks if the switch is in a stable state or not isn't it.

    so how can it be used in order to check if there is a 0 to 1 rising edge?
    Last edited by goodpranoy; 16th January 2014 at 16:46.



  20. #20
    Advanced Member level 5
    Points: 37,734, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,842
    Helped
    2011 / 2011
    Points
    37,734
    Level
    47

    Re: Finite State Machine working in simulation, but not working on actual FPGA board

    debouncing removes the 0/1/0/1 toggling you get when you move a switch, so the idea is after debouncing you get a single clean 0 -> 1 transition.



    •   AltAdvertisement

        
       

--[[ ]]--