EmbDev.net

Forum: FPGA, VHDL & Verilog PS/2 Interface


Author: Martin (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi, as part of an assignment I have to write a PS/2 interface. Here's 
the code that I've written so far:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity ps2_if is
  port(
    clk, rst : IN std_logic;
    ps2_clk : IN std_logic;
    ps2_dat : IN std_logic;
    data_out : OUT std_logic_vector(7 downto 0);
    valid_out : OUT std_logic
  );
end ps2_if;


architecture Behavioral of ps2_if is

  type State is (idle, receiving, transm_complete);
  signal CurrentState, NextState : State;
  signal goto_idle : std_logic;
  signal i : integer range 0 to 9 := 9;
  signal data : std_logic;

begin
  process(clk, rst)
  begin
    if rising_edge(clk) then
      if rst = '1' then
        data_out <= (others => '0');
        valid_out <= '0';
      else
        if CurrentState = transm_complete then
          valid_out <= '1';
          goto_idle <= '1';
        elsif CurrentState = idle then
          valid_out <= '0';
          goto_idle <= '0';
        end if;
        
        CurrentState <= NextState;
      end if;
    end if;
  end process;
  
  process(ps2_clk, CurrentState)
  begin
    NextState <= CurrentState;
    case CurrentState is
      when idle =>
        if falling_edge(ps2_clk) then
          NextState <= receiving;
          i <= i-1;
        end if;
      when receiving =>
        if falling_edge(ps2_clk) then
          if i = 0 then
            NextState <= transm_complete;
            i <= 7;
          else
            data_out(i-1) <= ps2_dat;      
            i <= i-1;
          end if;
        end if;
      when transm_complete =>
        if goto_idle = '1' then
          NextState <= idle;
        end if;
    end case;
  end process;
end Behavioral;

The problem I don't really know how to solve is: even though the code 
seems to be correct to me the simulator wouldn't the data from ps2_dat 
to the data_out vector. As I don't know VHDL well, I'm struggling to 
find the mistake.
I'm using the Xilinx Web Pack, v11.1 with the built-in simulator.
Does anybody see what the problem is?
Thanks a lot in advance!
Martin

Author: waxology (Guest)
Posted on:

Rate this post
0 useful
not useful
you couldn´t assign signals values in different processes!!
data_out <= (others => '0');
in the process above and
data_out(i-1) <= ps2_dat;
so both process will work parallel and data_out will probably be 'X'?
A simple structure to describe processe in vhdl is
[vhdl]
XXX: process(CLK, NRES)
begin
  if (NRES = '0') then
    ...
  elsif (rising/falling_edge(CLK) then
    ...
  end if;
end process

Author: Martin (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi waxology,
thanks a lot. It is now working! The command
data_out <= (others => '0');
really seems to have been the problem. But when I remove it the vector 
won't be reset on a rst event. Could you tell me how to get that right?
Another problem I noticed now is that valid_out which is supposed to be 
1 for one clock cycle when all the bits have arrived only goes back to 0 
after three cylces (clk cicles). Do you have any idea, why?
Martin

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

Rate this post
0 useful
not useful
  process(ps2_clk, CurrentState)
  begin
    NextState <= CurrentState;
    case CurrentState is
      when idle =>
        if falling_edge(ps2_clk) then   ----------------<<<
        :
        end if;
      when receiving =>
        if falling_edge(ps2_clk) then   ----------------<<<
        :
        end if;
      when transm_complete =>
        if goto_idle = '1' then
          NextState <= idle;
        end if;
    end case;
  end process;
end Behavioral;
You can try to simulate this, but you will never get it through the 
synthesizer.


  process(ps2_clk, CurrentState)
  begin
    NextState <= CurrentState;
CurrentState is combinatorial assigned to NextState, there's no 
clock or delay between. It's just the same. I don't think, thats what 
you really want  :-/


        :
        CurrentState <= NextState; -------------------<<<
      end if;
    end if;
  end process;
  
  process(ps2_clk, CurrentState)
  begin
    NextState <= CurrentState;   --------------------<<<
    :
Hmmm...
This looks much like a infinte loop.



> It is now working!
Believe me:
You're much farther away from your destination than you may think  :-o
You're not the first one to interface a keyboard to a FPGA, so have a 
look around how others are doing the job  ;-)

Author: Martin (Guest)
Posted on:

Rate this post
0 useful
not useful
Hello Lothar Miller,
thanks for the reply. I modified the first part you mentioned e.g. 
replacing the
if falling_edge(ps2_clk)...
parts by one right at the beginning of the process. Concerning the 
signals of the FSM I also modified the code. And well, it passed the 
synthesizer.
I think the main problem I have is that I have difficulties thinking in 
the hardware design way. That's why some parts of the code are somewhat 
strange.

Author: René D. (Company: www.dossmatik.de) (dose)
Posted on:

Rate this post
0 useful
not useful
You have to read

FPGA Prototyping by VHDL Examples written by Pong p.Chu

There are inside a PS2 interface example.

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.