PS/2 Interface

Guest #1296744
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
Guest #1296831
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
Guest #1297068
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
Moderator (Company: Titel) #1297074
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  ;-)
Guest #1297139
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.

Reply

Please log in before posting.

or

Log in with Google account

Registration is free and takes only a minute.

Register now