INOUT 端口的多路复用器
Mux for INOUT ports
大家好,我正在尝试交换 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';
有人能帮忙吗?
你那里有很多信号。我认为出于这个原因,我更喜欢示意图。不幸的是,该选项在 SE 站点上不可用(就像在 EE 站点上一样)。
第一眼我觉得你在哪里
试图通过 FPGA 构建双向路径。我试图了解正在发生的事情,但失败了。
我卡住了,因为你从来没有给 PS2K_CLK_OUT
赋值,但你确实使用了信号。 PS2K_DAT_OUT
也一样。因此,代码肯定是有缺陷的。
我建议您修复该部分,并通过添加更多类型的评论来更容易地了解正在发生的事情:
-- Mode A: Data comes from X and goes to Y
总的来说:
据我所知,不可能通过 FPGA 构建真正的双向路径。 (真的,我的意思是它可以自行确定信号方向)。您需要一个在输入和输出模式之间切换端口的信号。如果那是您所需要的,您唯一的选择是使用外部模拟开关或继电器。
诀窍是在每个双向引脚缓冲器之前放置两个多路复用器(一个用于输入,一个用于输出)。
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;
大家好,我正在尝试交换 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';
有人能帮忙吗?
你那里有很多信号。我认为出于这个原因,我更喜欢示意图。不幸的是,该选项在 SE 站点上不可用(就像在 EE 站点上一样)。
第一眼我觉得你在哪里 试图通过 FPGA 构建双向路径。我试图了解正在发生的事情,但失败了。
我卡住了,因为你从来没有给 PS2K_CLK_OUT
赋值,但你确实使用了信号。 PS2K_DAT_OUT
也一样。因此,代码肯定是有缺陷的。
我建议您修复该部分,并通过添加更多类型的评论来更容易地了解正在发生的事情:
-- Mode A: Data comes from X and goes to Y
总的来说:
据我所知,不可能通过 FPGA 构建真正的双向路径。 (真的,我的意思是它可以自行确定信号方向)。您需要一个在输入和输出模式之间切换端口的信号。如果那是您所需要的,您唯一的选择是使用外部模拟开关或继电器。
诀窍是在每个双向引脚缓冲器之前放置两个多路复用器(一个用于输入,一个用于输出)。
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;