EmbDev.net

Forum: FPGA, VHDL & Verilog PS/2 Interface


von Martin (Guest)


Rate this post
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:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
7
---- Uncomment the following library declaration if instantiating
8
---- any Xilinx primitives in this code.
9
--library UNISIM;
10
--use UNISIM.VComponents.all;
11
12
entity ps2_if is
13
  port(
14
    clk, rst : IN std_logic;
15
    ps2_clk : IN std_logic;
16
    ps2_dat : IN std_logic;
17
    data_out : OUT std_logic_vector(7 downto 0);
18
    valid_out : OUT std_logic
19
  );
20
end ps2_if;
21
22
23
architecture Behavioral of ps2_if is
24
25
  type State is (idle, receiving, transm_complete);
26
  signal CurrentState, NextState : State;
27
  signal goto_idle : std_logic;
28
  signal i : integer range 0 to 9 := 9;
29
  signal data : std_logic;
30
31
begin
32
  process(clk, rst)
33
  begin
34
    if rising_edge(clk) then
35
      if rst = '1' then
36
        data_out <= (others => '0');
37
        valid_out <= '0';
38
      else
39
        if CurrentState = transm_complete then
40
          valid_out <= '1';
41
          goto_idle <= '1';
42
        elsif CurrentState = idle then
43
          valid_out <= '0';
44
          goto_idle <= '0';
45
        end if;
46
        
47
        CurrentState <= NextState;
48
      end if;
49
    end if;
50
  end process;
51
  
52
  process(ps2_clk, CurrentState)
53
  begin
54
    NextState <= CurrentState;
55
    case CurrentState is
56
      when idle =>
57
        if falling_edge(ps2_clk) then
58
          NextState <= receiving;
59
          i <= i-1;
60
        end if;
61
      when receiving =>
62
        if falling_edge(ps2_clk) then
63
          if i = 0 then
64
            NextState <= transm_complete;
65
            i <= 7;
66
          else
67
            data_out(i-1) <= ps2_dat;      
68
            i <= i-1;
69
          end if;
70
        end if;
71
      when transm_complete =>
72
        if goto_idle = '1' then
73
          NextState <= idle;
74
        end if;
75
    end case;
76
  end process;
77
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

von waxology (Guest)


Rate this post
useful
not useful
you couldn´t assign signals values in different processes!!
1
data_out <= (others => '0');
in the process above and
1
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

von Martin (Guest)


Rate this post
useful
not useful
Hi waxology,
thanks a lot. It is now working! The command
1
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

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
1
  process(ps2_clk, CurrentState)
2
  begin
3
    NextState <= CurrentState;
4
    case CurrentState is
5
      when idle =>
6
        if falling_edge(ps2_clk) then   ----------------<<<
7
        :
8
        end if;
9
      when receiving =>
10
        if falling_edge(ps2_clk) then   ----------------<<<
11
        :
12
        end if;
13
      when transm_complete =>
14
        if goto_idle = '1' then
15
          NextState <= idle;
16
        end if;
17
    end case;
18
  end process;
19
end Behavioral;
You can try to simulate this, but you will never get it through the 
synthesizer.


1
  process(ps2_clk, CurrentState)
2
  begin
3
    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  :-/


1
        :
2
        CurrentState <= NextState; -------------------<<<
3
      end if;
4
    end if;
5
  end process;
6
  
7
  process(ps2_clk, CurrentState)
8
  begin
9
    NextState <= CurrentState;   --------------------<<<
10
    :
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  ;-)

von Martin (Guest)


Rate this post
useful
not useful
Hello Lothar Miller,
thanks for the reply. I modified the first part you mentioned e.g. 
replacing the
1
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.

von René D. (Company: www.dossmatik.de) (dose)


Rate this post
useful
not useful
You have to read

FPGA Prototyping by VHDL Examples written by Pong p.Chu

There are inside a PS2 interface example.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.