用于INOUT端口的多路复用器

时间:2018-07-25 22:05:24

标签: vhdl fpga inout

伙计们,我正在尝试交换2对INOUT信号,但到目前为止并没有多少成功。

我有两个PS / 2控制器,我想同时将PS2(1)转换为PS2(2)信号,同时将PS2(2)转换为PS2(1)信号。

也许用实际的(剪裁的)代码进行解释会更简单。

-- 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';

如您所见,我想使用控制信号“ ps2_mode_s”在鼠标和键盘之间进行信号交换。如果此信号为“ 0”,则我需要第一个端口的键盘和第二个端口的鼠标。如果为“ 1”,则相反,第一个端口为鼠标,第二个端口为键盘。

我已经尝试了一些变体,但是找不到合适的解决方案。

(编辑)如果我使用多路复用器,两个端口似乎都不会发送或接收任何数据。

(编辑)所有四个信号都连接到相应的模块。 PS2K_DAT_IN,PS2K_CLK_IN,PS2K_DAT_OUT,PS2K_CLK_OUT进入ps2键盘控制器,而其他四个PS2M_DAT_IN,PS2M_CLK_IN,PS2M_DAT_OUT,PS2M_CLK_OUT进入ps2鼠标控制器模块。如果我不使用多路复用器,则两个模块都可以正常工作,直接将信号连接到INOUT端口。

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';

请问有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

这是您那里存在的各种信号的混搭。我认为,出于这个原因,我宁愿选择示意图。不幸的是,该选项在SE网站上不可用(因为在EE网站上)。

乍一看,我给你的印象是 试图通过FPGA建立双向路径。我试图跟踪正在发生的事情,但失败了。

我陷入困境是因为您从未为PS2K_CLK_OUT分配值,但是您确实使用了信号。 PS2K_DAT_OUT也是一样。这样的代码肯定是有缺陷的。 我建议您修复该部分,并通过添加更多类型的注释来使操作更容易进行:

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

通常:
据我所知,不可能通过FPGA构建真正的双向路径。 (实际上,我的意思是它可以自行确定信号方向)。您需要一个信号来在输入和输出模式之间切换端口。如果需要,唯一的选择是使用外部模拟开关或继电器。

答案 1 :(得分:0)

诀窍是在每个双向引脚缓冲区之前放置两个多路复用器(一个用于输入,一个用于输出)。

groups = when(prediction==0,  "Iris-setosa") \
         .when(prediction==1,  "Iris-versicolor") \
         .when(prediction==2,  "Iris-virginica") \
         .otherwise(None)