0

Hey guys I'm trying to exchange 2 pairs of INOUT signals, but without much sucess so far.

I have two PS/2 controlers and I would like to exchange the PS2(1) to PS2(2) signals and at same time PS2(2) to PS2(1) signals.

Perhaps it's simpler to explain with the actual (sniped) code.

-- external ports 
ps2_clk_io        : inout std_logic     := 'Z';
ps2_data_io       : inout std_logic     := 'Z';
ps2_mouse_clk_io  : inout std_logic     := 'Z';
ps2_mouse_data_io : inout std_logic     := 'Z';


-- signals
signal ps2_mode_s   : std_logic := '0';
signal PS2K_DAT_IN  : std_logic;
signal PS2K_DAT_OUT : std_logic;
signal PS2K_CLK_IN  : std_logic;
signal PS2K_CLK_OUT : std_logic;
signal PS2M_DAT_IN  : std_logic;
signal PS2M_DAT_OUT : std_logic;
signal PS2M_CLK_IN  : std_logic;
signal PS2M_CLK_OUT : std_logic;

signal ps2_data_out : std_logic;
signal ps2_clk_out      : std_logic;
signal ps2_mouse_data_out   : std_logic;
signal ps2_mouse_clk_out    : std_logic;

 -- LOGIC BLOCK
 -- PS/2 keyboard
 PS2K_DAT_IN <= ps2_data_io when ps2_mode_s = '0' else ps2_mouse_data_io;
 PS2K_CLK_IN <= ps2_clk_io  when ps2_mode_s = '0' else ps2_mouse_clk_io;

 ps2_data_out <= PS2K_DAT_OUT when ps2_mode_s = '0' else PS2M_DAT_OUT;
 ps2_clk_out  <= PS2K_CLK_OUT when ps2_mode_s = '0' else PS2M_CLK_OUT;

 ps2_data_io <= '0' when ps2_data_out = '0' else 'Z';
 ps2_clk_io  <= '0' when ps2_clk_out  = '0' else 'Z';

 -- PS/2 Mouse
 PS2M_DAT_IN <= ps2_mouse_data_io when ps2_mode_s = '0' else ps2_data_io;
 PS2M_CLK_IN <= ps2_mouse_clk_io  when ps2_mode_s = '0' else ps2_clk_io;

 ps2_mouse_data_out <= PS2M_DAT_OUT when ps2_mode_s = '0' else PS2K_DAT_OUT;
 ps2_mouse_clk_out  <= PS2M_CLK_OUT when ps2_mode_s = '0' else PS2K_CLK_OUT;

 ps2_mouse_data_io <= '0' when ps2_mouse_data_out = '0' else 'Z';
 ps2_mouse_clk_io  <= '0' when ps2_mouse_clk_out  = '0' else 'Z';

As you can see, I would like to exchage the signals between a mouse and a keyboard, using the control signal "ps2_mode_s". If this signal is '0', I need the keyboard on the first port and the mouse on the second. If it's '1', the oposite, mouse on first port and keyboard on second.

I already tried some variations, but I didn't find a proper solution.

(EDIT) Both ports appear to not send or receive any data if I use the mux.

(EDIT) All four signals are connected to the respective modules. PS2K_DAT_IN, PS2K_CLK_IN , PS2K_DAT_OUT, PS2K_CLK_OUT goes to a ps2 keyboard controller and the other four PS2M_DAT_IN, PS2M_CLK_IN , PS2M_DAT_OUT, PS2M_CLK_OUT goes to the ps2 mouse controller module. Both modules are working if I dont use the mux, connecting the signals directly to the INOUT ports.

PS2K_DAT_IN <= ps2_data_io;
ps2_data_io <= '0' when (PS2K_DAT_OUT = '0') else 'Z';
PS2K_CLK_IN <= ps2_clk_io;
ps2_clk_io  <= '0' when (PS2K_CLK_OUT = '0') else 'Z';

PS2M_DAT_IN <= ps2_mouse_data_io;
ps2_mouse_data_io <= '0' when (PS2M_DAT_OUT = '0') else 'Z';
PS2M_CLK_IN <= ps2_mouse_clk_io;
ps2_mouse_clk_io <= '0' when (PS2M_CLK_OUT = '0') else 'Z';

Can anyone help, please?

DFL
  • 3
  • 3
  • 1
    Welcome on StackOverflow. You could, maybe, visit the [Asking section](https://stackoverflow.com/help/asking) to better understand how to ask good questions and, especially, what a [Minimal, Complete, and Verifiable example (MCVE)](https://stackoverflow.com/help/mcve) is. Your question, for instance, does not even contain a clear description of the problem you encountered (error messages, unwanted behavior...), while this is definitely needed. – Renaud Pacalet Jul 26 '18 at 08:26
  • Sorry, I completely forgot to write about the problem. Both ports appear to not send or receive any data if I use the mux. – DFL Jul 26 '18 at 09:46
  • 1
    Perhaps you could supply a [mcve] and whether you have a problem in implementation or simulation. If implementation, the vendor's particular tool chain and revision. The supporting language for synthesis is IEEE Std 1076-2008, 16.8.2.4.10 Interpretation of the high-impedance value ('Z'), IEEE Std 1076.6-2004 (withdrawn) 6.3.1 Three-state logic from ‘Z’ assignment. FPGA synthesis may depend on the assignment target being a device pin (e.g. Vivado will transform internal signals 'Z' assignment to equivalent logic). If simulation, the MCVe would allow examination of a specific problem. –  Jul 26 '18 at 18:15

2 Answers2

0

It is rather a mish-mash of signals you have in there. I think in this cause I would have preferred a schematic. Unfortunately that option is not available on the SE site (As it is on the EE site).

From the first glance I had the impression that you where trying to build a bi-directional path through an FPGA. I tried to follow what was going on but failed.

I got stuck because you never assign a value to PS2K_CLK_OUT, but you do use the signal. The same for PS2K_DAT_OUT. As such the code is definitely flawed. I suggest you fix that part and make it easier to follow what is going on by add more comments of the type:

-- Mode A: Data comes from X and goes to Y

In general:
As far as I know it is NOT possible to build a truly bi-directional path through an FPGA. (With truly, I mean it self-determines the signal direction). You need a signal which switches the ports between input and output mode. If that is what you need, your only option is to use an external analog switch or a relay.

Oldfart
  • 6,104
  • 2
  • 13
  • 15
  • Thanks for the answer. All four signals are connected to the respective modules. PS2K_DAT_IN, PS2K_CLK_IN , PS2K_DAT_OUT, PS2K_CLK_OUT goes to a ps2 keyboard controller and the other four signals goes to the ps2 mouse module. In both cases its working if I dont use the mux, connecting the modules directly to the INOUT ports. – DFL Jul 26 '18 at 09:54
0

The trick is to put two multiplexers (one for input, one for output) before each bidirectional pin buffer.

library ieee;
use ieee.std_logic_1154.all;

entity PS2Switch is
    port(
        -- control
        mode_s : in std_logic;
        -- keyboard ps/2 block
        kbd_clk_in   : in  std_logic;
        kbd_clk_out  : out std_logic;
        kbd_data_in  : in  std_logic;
        kbd_data_out : out std_logic;
        -- mouse ps/2 block
        mouse_clk_in   : in  std_logic;
        mouse_clk_out  : out std_logic;
        mouse_data_in  : in  std_logic;
        mouse_data_out : out std_logic;
        --port A
        prtA_clk  : inout std_logic;
        prtA_data : inout std_logic;
        --port B
        prtB_clk  : inout std_logic;
        prtB_data : inout std_logic
        );
end entity;

architecture rtl of PS2Switch is
    signal prtA_clk_out  : std_logic;
    signal prtA_data_out : std_logic;
    signal prtB_clk_out  : std_logic;
    signal prtB_data_out : std_logic;
begin
    -- output muxes
    kbd_clk_out    <= prtA_clk  when mode_s = '0' else prtB_clk;
    kbd_data_out   <= prtA_data when mode_s = '0' else prtB_data;
    mouse_clk_out  <= prtA_clk  when mode_s = '1' else prtB_clk;
    mouse_data_out <= prtA_data when mode_s = '1' else prtB_data;

    -- input muxes
    prtA_clk_out  <= kbd_clk_in  when mode_s = '0' else mouse_clk_in;
    prtA_data_out <= kbd_data_in when mode_s = '0' else mouse_data_in;
    prtB_clk_out  <= kbd_clk_in  when mode_s = '1' else mouse_clk_in;
    prtB_data_out <= kbd_data_in when mode_s = '1' else mouse_data_in;

    -- tristate buffers (output pins)
    prtA_clk  <= '0' when prtA_clk_out  = '0' else 'Z';
    prtA_data <= '0' when prtA_data_out = '0' else 'Z';
    prtB_clk  <= '0' when prtB_clk_out  = '0' else 'Z';
    prtB_data <= '0' when prtB_data_out = '0' else 'Z';
end architecture;
JHBonarius
  • 10,824
  • 3
  • 22
  • 41