因此,我听说在不知道协议(或者没有控制线)的情况下通过双向数据端口是不可能的。(见tie two inout together vhdl)
然而,我真的很想这样做,我真的不想知道协议。所以..。
我想从SIM智能卡(从电话)传递数据线。目前,除了数据线之外,所有东西都可以工作,这是双向的。
我还没有确认这一点,但我的范围暗示这条线被拉得很高,任何一方都可以根据需要把它拉下来。我想利用这条线在外面拉得很高的好处。
我想尝试下面的注释代码中列出的两个选项:
architecture Behavioral of SIM_Select_Test_A is
begin
process(MOD_CLK, MOD_RST)
begin
SIM_RST <= MOD_RST;
SIM_CLK <= MOD_CLK;
end process;
-- OPTION ONE1
-- process(MOD_CLK, MOD_DATA, SIM_DATA)
-- begin
-- IF MOD_DATA = '0' THEN
-- SIM_DATA <= '0';
-- ELSE
-- IF SIM_DATA = '0' THEN
-- MOD_DATA <= '0';
-- ELSE
-- MOD_DATA <= MOD_DATA;
-- SIM_DATA <= SIM_DATA;
-- END IF;
-- END IF;
-- end process;
-- OPTION 2
-- process(MOD_CLK, MOD_DATA, SIM_DATA)
-- begin
-- IF MOD_DATA = '0' THEN
-- SIM_DATA <= '0';
-- ELSE
-- IF SIM_DATA = '0' THEN
-- MOD_DATA <= '0';
-- ELSE
-- MOD_DATA <= 'Z';
-- SIM_DATA <= 'Z';
-- END IF;
-- END IF;
-- end process;
end Behavioral;请有人确认一下,如果我把SIM_DATA开得低,我不会掉进第二个,因此把MOD_DATA弄低(即进入某种循环逻辑)。
任何意见,如果我应该采取这一途径,或我绝对需要知道的协议。如果是这样的话,我想我会开始研究:
谢谢你,库尔特
编辑:添加我的实体声明:
entity SIM_Select_Test_A is
Port ( SIM_VCC : OUT STD_LOGIC;
SIM_DATA : inout STD_LOGIC;
SIM_RST : out STD_LOGIC;
SIM_CLK : out STD_LOGIC;
MOD_VCC : in STD_LOGIC;
MOD_DATA : inout STD_LOGIC;
MOD_RST : in STD_LOGIC;
MOD_CLK : in STD_LOGIC);
attribute bufg : string;
attribute bufg of MOD_CLK : signal is "CLK";
attribute bufg of MOD_DATA : signal is "OE";
end SIM_Select_Test_A;编辑2:哇,谢谢你的详细答复。是的,我明白你在说什么。我想我所希望的是,我可以在代码中添加一些智能,以便在wire1控制线路和优先排序时意识到这一点。所以你的评论让我把我的想法正规化了,这就是我得到的。对伪代码表示歉意,但我希望它能使事情变得更清楚,而且当我在脑海中编译它时,它总是工作得很好:)
IF (wire1 = '0' AND flag = '0') THEN
wire2 <= '0' <--here wire1 gets priority and wire2 is controlled based on wire1. My hope is that when it is at this point in the code then it does NOT fall into the else statement.
ELSE <-- IF (wire1 is NOT low OR there is a flag) THEN check if wire2 is low (which in my head seems slightly different than elsif
IF (wire2 = '0') THEN
wire1 <= '0';
flag <= '1'; <-- I think this is where there might be a problem. I am trying to use the flag to tell the outer IF that the CPLD holding wire1 low and to ignore it
ELSE <--neither are being held low externally
wire1 <= 'HIZ';
wire2 <= 'HIZ';
flag <= '0';
END IF
END IF;我会看看我是否可以模拟今天,但感谢您的任何评论。
发布于 2015-12-03 10:06:29
这个答案是适用的,如果你至少可以对被截获的双向总线的数据传输做出一些假设。如果一个人不能做出任何假设,那么my other answer仍然是正确的。
拦截应该是这样的:IC1 <--wire1--> FPGA <--wire2--> IC2。
一个解决方案是可能的,如果一个人至少可以做出以下假设:
解决方案需要一个有限状态机,其中状态保持跟踪哪一边(IC1 oder IC2)实际拉下线。如果一个IC拉下他的电线,FPGA就会拉下另一个。如果集成电路释放电线,电线是由电阻拉起的,那么FPGA也会释放其他电线。但现在,我们必须等到另一根电线被它自己的电阻拉上来,然后再检查那根电线是否向另一个方向传输数据。
以下是代码:
library ieee;
use ieee.std_logic_1164.all;
entity intercept_open_drain_bus2 is
port (
clock : in std_logic;
wire1 : inout std_logic;
wire2 : inout std_logic);
end entity intercept_open_drain_bus2;
architecture rtl of intercept_open_drain_bus2 is
type state_t is (IDLE, PULLDOWN1, WAIT1, PULLDOWN2, WAIT2);
signal state : state_t := IDLE;
begin
-- Moore outputs from finite state machine
wire1 <= '0' when state = PULLDOWN1 else 'Z';
wire2 <= '0' when state = PULLDOWN2 else 'Z';
-- finite state machine
process(clock)
begin
if rising_edge(clock) then
case state is
when IDLE =>
if wire2 = '0' then
state <= PULLDOWN1;
elsif wire1 = '0' then
state <= PULLDOWN2;
end if;
when PULLDOWN1 =>
if wire2 /= '0' then -- 'H' or '1'
state <= WAIT1;
end if;
when WAIT1 => -- wait until wire1 is pulled-up by the resistor
if wire1 /= '0' then
state <= IDLE;
end if;
when PULLDOWN2 =>
if wire1 /= '0' then -- 'H' or '1'
state <= WAIT2;
end if;
when WAIT2 => -- wait until wire2 is pulled-up by the resistor
if wire2 /= '0' then
state <= IDLE;
end if;
end case;
end if;
end process;
end architecture rtl;这是测试台:
library ieee;
use ieee.std_logic_1164.all;
entity intercept_open_drain_bus2_tb is
end entity intercept_open_drain_bus2_tb;
architecture sim of intercept_open_drain_bus2_tb is
signal clock : std_logic := '1';
signal wire1 : std_logic;
signal wire2 : std_logic;
signal STOPPED : boolean := false;
begin
DUT: entity work.intercept_open_drain_bus2
port map (
clock => clock,
wire1 => wire1,
wire2 => wire2);
-- 100 MHz FPGA clock from external oscillator
clock <= not clock after 5 ns when not STOPPED;
-- external PULLUP resistor
wire1 <= 'H';
wire2 <= 'H';
WaveGen_Proc: process
begin
-- both far-end ICs have their outputs disabled
wire1 <= 'Z';
wire2 <= 'Z';
wait until rising_edge(clock);
assert (wire1 = 'H') and (wire2 = 'H') report "initial pullup failed." severity error;
-- IC 1 pulls down wire 1 for at least 10 FPGA clock cycles
wire1 <= '0';
wait until rising_edge(clock);
-- wire2 is changing here in the real world
for i in 2 to 10 loop
wait until rising_edge(clock);
assert (wire2 = '0') report "passing from wire1 failed." severity error;
end loop;
-- IC 1 disables its output again for at least 10 FPGA clock cycles
wire1 <= 'Z';
wait until rising_edge(clock);
-- wire2 is changing here in the real world
for i in 2 to 10 loop
wait until rising_edge(clock);
assert (wire1 = 'H') and (wire2 = 'H') report "pullup after transfer failed." severity error;
end loop;
-- IC 2 pulls down wire 1 for at least 10 FPGA clock cycles
wire2 <= '0';
wait until rising_edge(clock);
-- wire1 is changing here in the real world
for i in 2 to 10 loop
wait until rising_edge(clock);
assert (wire1 = '0') report "passing from wire2 failed." severity error;
end loop;
-- IC 2 disables its output again for at least 10 FPGA clock cycles
wire2 <= 'Z';
wait until rising_edge(clock);
-- wire1 is changing here in the real world
for i in 2 to 10 loop
wait until rising_edge(clock);
assert (wire2 = 'H') and (wire1 = 'H') report "pullup after transfer failed." severity error;
end loop;
STOPPED <= true;
wait;
end process WaveGen_Proc;
end architecture sim;现在,模拟器输出看起来很好:

发布于 2015-12-02 21:42:38
编辑这个答案只适用于不能对被截获的总线上的数据传输做出任何假设的情况。请在my other answer上看一看。
即使使用由电阻器拉起的开路漏/开路集电极总线,也无法做到这一点。电阻器实际上可以集成到一个集成电路,但它们总是放在垫和I/O驱动器之间,因此,在总线上。
拦截应该是这样的:IC1 <--wire1--> FPGA <--wire2--> IC2。
假设被截取的总线在启动后处于空闲状态,那么两条线都会被电阻拉得很高。如果那样的话,IC1就会拉下wire1,FPGA也会拉下wire2。但是现在,FPGA也会读到wire2被拉下来,因此也会拉下wire1。现在,两条电线都是由FPGA拉下来的。即使IC1禁用其输出驱动程序,也会保留此状态。
如果你不相信,试试这个VHDL代码。
library ieee;
use ieee.std_logic_1164.all;
entity intercept_open_drain_bus is
port (
wire1 : inout std_logic;
wire2 : inout std_logic);
end entity intercept_open_drain_bus;
architecture rtl of intercept_open_drain_bus is
begin
-- Assume port is pulled-up externally.
wire1 <= '0' when wire2 = '0' else 'Z';
wire2 <= '0' when wire1 = '0' else 'Z';
end architecture rtl;下面是运行上述场景的testbench:
library ieee;
use ieee.std_logic_1164.all;
entity intercept_open_drain_bus_tb is
end entity intercept_open_drain_bus_tb;
architecture sim of intercept_open_drain_bus_tb is
signal wire1 : std_logic;
signal wire2 : std_logic;
begin
DUT: entity work.intercept_open_drain_bus
port map (
wire1 => wire1,
wire2 => wire2);
-- external PULLUP resistor
wire1 <= 'H';
wire2 <= 'H';
WaveGen_Proc: process
begin
-- both far-end ICs have their outputs disabled
wire1 <= 'Z';
wire2 <= 'Z';
wait for 1 ns;
assert (wire1 = 'H') and (wire2 = 'H') report "initial pullup failed." severity error;
-- IC 1 pulls down wire 1
wire1 <= '0';
wait for 1 ns;
assert (wire2 = '0') report "passing from wire1 failed." severity error;
-- IC 1 disables its output again
wire1 <= 'Z';
wait for 1 ns;
assert (wire1 = 'H') and (wire2 = 'H') report "pullup after transfer failed." severity error;
wait;
end process WaveGen_Proc;
end architecture sim;这是模拟器输出,显示最后一个测试用例失败(在黄色标记的右边):

https://stackoverflow.com/questions/34027858
复制相似问题