EmbDev.net

Forum: FPGA, VHDL & Verilog Finite State Machine working in simulation, but not working on actual FPGA board


Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
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.
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.

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;



: Edited by User
Author: daniel__m (Guest)
Posted on:

Rate this post
1 useful
not useful
vhdl newbie wrote:

> elsif (rising_edge(clk)) then
>   current_s <= next_s;   --state change.
>   pc_reset<='0';
> end if;
...
> when in_s =>         --when current state is "in_s"
>     if rising_edge(enter) then
>     next_s <= fetch;
>     else
>     next_s <= in_s;
>     end if;

this is a very ugly way to describe hardware and is a complex type of 
gated clock! I wonder, that this gets synthesized.

I disbelieve, that even the simulation works completely. The state 
machine would only switch, if two signal edges occures at the same time: 
clk and enter. This is a infinity small time window.

The usual way is to capture the enter signal and compare the captured 
signal with the actual value.

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
sir thanks for your reply.

i've edited my code and is posting it now.

the previous code was a wrong code and was not the code which i wanted.

posting the actual code here.

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;

Author: Typo (Guest)
Posted on:

Rate this post
1 useful
not useful
    enter_r<=enter;
    if(enter_r='0' and enter='1') then
    next_s <= fetch;
    else
    next_s <= in_s;
    end if;

What do you expect this to do? As you described a strictly combinatorial 
process, the condition is constantly false.

This is'nt a matter for a total newbie I think. You shall consider basic 
VHDL first and try simple constructions using the principle before 
trying such things and get lost in overwhelmingly large texts.

By the way:
1. Please add such lengthy code as an attachment rather than literally 
as a part of the posts text.
2. You do not write programs in VHDL but describe structures Please 
consider this as it may be the very reason for using the construct which 
I cited above.

: Edited by Moderator
Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
Typo wrote:
> enter_r<=enter;
>     if(enter_r='0' and enter='1') then
>     next_s <= fetch;
>     else
>     next_s <= in_s;
>     end if;
>
> What do you expect this to do?


sir, i expect this to give a rising edge detection of the enter input.

Typo wrote:
> Please add such lengthy code as an attachment rather than literally
> as a part of the posts text.

i'll keep that in mind :)

Author: Typo (Guest)
Posted on:

Rate this post
0 useful
not useful
>Sir, ...

No need to be so formal here. Just call us be our nicks. :-)

> ... i expect this to give a rising edge detection of the enter input.

I thought so. But it seem i was a bit too laconic.
This:

>As you described a strictly combinatorial
>process, the condition is constantly false.

contained the hint.

If you are unsure if something is combinatorical or clocked have look at 
the implementation. How you may have a look at it depends on the 
software you use.

However, if enter is not clocked into a flip-flop the code is not proper 
for detecting edges.

Author: Today (Guest)
Posted on:

Rate this post
0 useful
not useful
As our "famous" VHDL-crack Lothar Miller seems not to be present I add a 
link to an edge detection here: 
http://www.lothar-miller.de/s9y/categories/18-Flan...

The text is in German but the code shall be comprehensible either.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> i've edited my code and is posting it now.
Pls attach long VHDL code as *.vhd file!
Its also qouted in the box where you enter your text:
Rules — please read before posting

    Post long source code as attachment, not in the text


Typo wrote:
> not write programs in VHDL but describe structures ...
... or hardware behaviour.
But as the word itself says: VHDL is a hardware description language, 
not a hardware programming language.

vhdl newbie wrote:
> i've edited my code and is posting it now.
And ist this code ok in simulation? I assume not, because:
> process (current_s,enter,input,a_zero_status)
enter_r is missing in this sensitivity list.

> load_a <= "UUU";
> load_b <= "UUU";
Do you think the synthesizer can implement 'U' level in real hardware? 
Which voltage would one measure on a 'U' level?

: Edited by Moderator
Author: Typo (Guest)
Posted on:

Rate this post
0 useful
not useful
@ Lothar Miller
>... or hardware behaviour.
Grmbl. Let's have an in depth discussion about that matter. Someday. :-)

Author: vhdl newbie (Company: none) (pranoy)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Typo wrote:
> if enter is not clocked into a flip-flop the code is not proper
> for detecting edges.

i've changed my code now. (check line 39)
please check my code and see whether it is correct.

Lothar Miller wrote:
> And ist this code ok in simulation? I assume not

YES it is working in Modelsim simulation.

Lothar Miller wrote:
>> load_a <= "UUU";
>> load_b <= "UUU";
> Do you think the synthesizer can implement 'U' level in real hardware?
> Which voltage would one measure on a 'U' level?

when i synthesised it in xilinx, i changed U to Z.
this happened because i copied the code from Modelsim.
i've attached the new code.

: Edited by User
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> Lothar Miller wrote:
>> And ist this code ok in simulation? I assume not
> YES it is working in Modelsim simulation.
Then you may have a different behaviour in reality, because the 
sensitivity list is for simulation only!

> when i synthesised it in xilinx, i changed U to Z.
You cannot have a 'Z' level inside nowadays FPGAs. Tristate levels are 
resolved with a multiplexer by the synthesizer.

> i've attached the new code.
enter_r is missing in this sensitivity list. I already mentioned this, 
didn't I?

> enter : in std_logic;
Where does this signal come from? Is it a asynchronous signal from 
outside the FPGA (eg. a key, switch)? If so, then you have to sync this 
signal to the 'clk' clock domain...

Author: vhdl newbie (Company: none) (pranoy)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> enter_r is missing in this sensitivity list.

done it now.

Lothar Miller wrote:
>> enter : in std_logic;
> Where does this signal come from? Is it a asynchronous signal from
> outside the FPGA (eg. a key, switch)?

YES, it is an async signal from outside (a dip switch or a push button).

Lothar Miller wrote:
> If so, then you have to sync this
> signal to the 'clk' clock domain.
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;


is this how to sync enter with the clock?

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> is this how to sync enter with the clock?
In that snippet enter is not synced up to now. To be in sync you must 
add (at least) one more flipflop stage. So it should look like   enter 
-> enter_s -> enter_r   and then enter_s and enter_r are used for edge 
detection. But the link for this was already posted...

What happens without synchronizing is shown there (try Google 
translate):
http://www.lothar-miller.de/s9y/archives/64-State-...

: Edited by Moderator
Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
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.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> is there any problem with my code?
Who knows? Post your VHDL file(s). Otherwise only guessing around is 
possible...

Also write some words about the hadrware: which FPGA? How are the 
switches connected? ...

And: usually you MUST begin a new thread for a new question. It is not 
good practice to take over someone others thread.

Author: vhdl newbie (Company: none) (pranoy)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> Post your VHDL file(s)

i've posted it previously.

posting it again :)


Lothar Miller wrote:
> which FPGA?

Spartan 3

Lothar Miller wrote:
> How are the
> switches connected?

the enter is connected to a dip switch on the FPGA board itself.

Lothar Miller wrote:
> It is not
> good practice to take over someone others thread.

this thread was started by me :)

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> Lothar Miller wrote:
>> It is not good practice to take over someone others thread.
> this thread was started by me :)
Hmmm, okokokokok... :-/

vhdl newbie wrote:
>   enter_r<=enter;
> end if;
> end process;
> is this how to sync enter with the clock?
Yes, but afterwards you should use the sync'ed enter in your 
description...

vhdl newbie wrote:
> 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.
You use a dip switch as the clock source?
That will never work unless its a bounce-free switch.

> 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.
It doesn't do it in the same time, but it does it within 50ns one after 
the other. For you this is looking like "the same time".

> is there any problem with my code?
Not more than already mentioned. Its a problem with your hardware now.

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> Its a problem with your hardware now.

will giving it to a debounce circuit work??

what will be the delay after which the switch reaches a stable state?

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
I don't know, because theres no answer to the question about the clock 
source: where does "clk" come from?

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
Lothar Miller wrote:
>
> source: where does "clk" come from?

clock is FPGA clock (50MHz)

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> 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
And what is that "dip swith"? Is it connected to the "enter" signal?

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
yes

enter is connected to the dip switch.

i got this code from the net for debouncing.

how can i get a clean 0 to 1 transition from this?

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY debounce IS
  GENERIC(
    counter_size  :  INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
  PORT(
    clk     : IN  STD_LOGIC;  --input clock
    button  : IN  STD_LOGIC;  --input signal to be debounced
    result  : OUT STD_LOGIC); --debounced signal
END debounce;

ARCHITECTURE logic OF debounce IS
  SIGNAL flipflops   : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops
  SIGNAL counter_set : STD_LOGIC;                    --sync reset to zero
  SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output
BEGIN

  counter_set <= flipflops(0) xor flipflops(1);   --determine when to start/reset counter
  
  PROCESS(clk)
  BEGIN
    IF(clk'EVENT and clk = '1') THEN
      flipflops(0) <= button;
      flipflops(1) <= flipflops(0);
      If(counter_set = '1') THEN                  --reset counter because input is changing
        counter_out <= (OTHERS => '0');
      ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met
        counter_out <= counter_out + 1;
      ELSE                                        --stable input time is met
        result <= flipflops(1);
      END IF;    
    END IF;
  END PROCESS;
END logic;

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> i got this code from the net for debouncing.
Aha, the copy&paste generation...

> how can i get a clean 0 to 1 transition from this?
Why not thinking for yourself? I already posted the skeletons for this 
edge detection in http://embdev.net/topic/320582#3483355

Or at least copying from the right place?
http://www.lothar-miller.de/s9y/categories/18-Flan...

Ok, give me your hand and I will guide you through this mission 
impossible:
signal enter_r, enter_s :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.
  
  enter_r <=enter_s;
  enter_s <=enter;
  
  pc_reset<='0';
end if;
end process;

--state machine process.
process (current_s,enter_s,enter_r,input,a_zero_status)
begin
  case current_s is
    
    when fetch =>        --when current state is "fetch"
    next_s <= decode;
    :    
    when in_s =>         --when current state is "in_s"
    if enter_s='1' and enter_r='0' then -- rising edge
       next_s <= fetch;
    else
       next_s <= in_s;
    end if;
    :

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> Why not thinking for yourself? I already posted the skeletons for this
> edge detection in http://embdev.net/topic/320582#3483355

did some thinking and was gonna do like this

route the enter signal to the input of the debouncer module and take the 
output of this as the enter for my FSM.

OR

route the enter signal to the input of the debouncer module and take the 
output of this to DFF series and its output as the enter for my FSM
will my problems be solved??

asked that to see if anyone has a more clean idea. :)

Lothar Miller wrote:
> when in_s =>         --when current state is "in_s"
>     if enter_s='1' and enter_r='0' then -- rising edge
>        next_s <= fetch;

if the switch is bouncing, then will this work ?
i tried this and didn't work.

Lothar Miller wrote:
> Aha, the copy&paste generation...

as the input instruction was not working previously, i made some changes 
in my project and made the program memory and data memory into RAMs.

will start a new thread about this in the near future.


so, copying was the last resort :)

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> if the switch is bouncing, then will this work ?
No, you're right, it won't work. The 50MHz clock is too fast...

> so, copying was the last resort :)
The debouncing unit you found is a counter, that is reset, when the 
input changes. Otherwise it counts up and when it reaches a certain 
level the input is regarded as stable. Then the input signal is 
forwarded.

You could write this in a few lines in your code:
signal enter_r, enter_s :std_logic;
constant maxbounce : integer := 50000;
signal stablecnt : integer 0 to maxbounce ;

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.
  
  enter_r <=enter_s;
  enter_s <=enter;
  if enter_s/=enter_r then
     stablecnt <= 0;
  elsif stablecnt < maxbounce then
     stablecnt <= stablecnt+1;
  end if;

  pc_reset<='0';
end if;
end process;

--state machine process.
process (current_s,enter_s,stablecnt,input,a_zero_status)
begin
  case current_s is
    
    when fetch =>        --when current state is "fetch"
    next_s <= decode;
    :    
    when in_s =>         --when current state is "in_s"
    if stablecnt=maxbounce and enter_s='1' then -- debounced rising edge
       next_s <= fetch;
    else
       next_s <= in_s;
    end if;
    : 


: Edited by Moderator
Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
i gave it a go.

It is working but there is a small problem.

before the program is executed, we should give an additional enter( so 
to input a data we now need 2 rising edges of enter instead of 1).

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> before the program is executed, we should give an additional enter( so
> to input a data we now need 2 rising edges of enter instead of 1).
No. Forget that whole "rising edge view". What you really need is one 
more state at the start of the whole thing. And to leave that state you 
check the switch in the same way as you do it now in the in_s state.

BTW: Did I already mention the word "thinking"?

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> BTW: Did I already mention the word "thinking"?

i did that, but i added an NOP state after the in_s state.

here i checked if the enter signal attains a zero back. :)

Lothar Miller wrote:
> And to leave that state you
> check the switch in the same way as you do it now in the in_s state.

i didn't understand this.

did you mean to check if enter is a 0 or 1?

Author: vhdl newbie (Company: none) (pranoy)
Posted on:
Attached files:

Rate this post
0 useful
not useful
guys i'm posting my complete project files here.

if anyone can program a spartan3 with these files please check why u 
need 3 enter signals for entering 2 values.

the present program is

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

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
vhdl newbie wrote:
> if anyone can program a spartan3 with these files please check
Before programming the Almighty set the simulation. Which one of the 
files is the test bench? What result do you get when you are simualting 
your code?

>       if alu_enable='1' then
>          if (clock'event and clock='1') then
Where did you find this way to describe a clock enable?
Usually in the synthesis guidelines you will find it the other way 
round:
  if (clock'event and clock='1') then
     if alu_enable='1' then

Author: vhdl newbie (Company: none) (pranoy)
Posted on:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> Which one of the
> files is the test bench? What result do you get when you are simualting
> your code?

i think i have drifted away from the subject of this thread
so i'm starting a new thread.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.