Altera_Forum
Honored Contributor
12 years agoSingle wire can bus and bidirectional pin coding
Hi all,
I am a beginner, trying to implement a One-wire CAN bus coupler logic on a Cyclone IV FPGA. The FPGA communicates to a disconnectable external slave device via a pin using CAN bus. The pin can be configured as an Input/Output or Bidirectional at anytime. However I am facing issues trying to simulate just the IO pin on modelsim. Setup:- slave device drives the wire using open drain (bus is normally high, slave device pulls it down during communication)
- weak pull up resistor enabled for IO pin on FPGA. (to pull the pin high when the slave device is removed)
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY bidir_port IS
PORT(
bidir : INOUT STD_LOGIC; --to bidirectional pin
oe_ie : IN STD_LOGIC_VECTOR(1 downto 0); --direction select
clk : IN STD_LOGIC; --to clock the registers
inp : IN STD_LOGIC; --input from logic
outp : OUT STD_LOGIC --output to logic
);
END bidir_port;
ARCHITECTURE logic OF bidir_port IS
SIGNAL a : STD_LOGIC; -- DFF that stores
SIGNAL b : STD_LOGIC; -- DFF that stores
BEGIN
PROCESS(clk)
BEGIN
if clk='1' and clk'event then
a <= inp;
outp <= b;
END IF;
END PROCESS;
PROCESS (oe_ie, bidir,a,inp) -- Behavioral representation
BEGIN -- of tri-states.
case oe_ie is
when "00" => -- no connection
bidir <= 'Z';
b <= '1';
when "01" => -- output
bidir <= a;
b <='1' ;
when "10" => -- input
bidir <= 'Z';
b <= to_X01(bidir);
when "11" =>
bidir <= a;
b <= to_X01(bidir);
when others =>
bidir <= 'Z';
b <= to_X01(bidir);
end case;
END PROCESS;
END logic;
I have driven the bidirectional pin on the test bench using 'H' logic to signify weak pull up. In simulation the output will be "X" undefined if the both devices are driving the wire as well. Picture: https://www.alteraforum.com/forum/attachment.php?attachmentid=7712 I realised that if i changed my code to use 'H' instead of '1' when driving the bus, the simulation appears better. LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY bidir_port IS
PORT(
bidir : INOUT STD_LOGIC;
oe_ie : IN STD_LOGIC_VECTOR(1 downto 0);
clk : IN STD_LOGIC;
inp : IN STD_LOGIC;
outp : OUT STD_LOGIC
);
END bidir_port;
ARCHITECTURE logic OF bidir_port IS
SIGNAL a : STD_LOGIC; -- DFF that stores
SIGNAL b : STD_LOGIC; -- DFF that stores
BEGIN
PROCESS(clk)
BEGIN
if clk='1' and clk'event then
a <= inp;
outp <= b;
END IF;
END PROCESS;
PROCESS (oe_ie, bidir,a,inp) -- Behavioral representation
BEGIN -- of tri-states.
case oe_ie is
when "00" => -- no connection
bidir <= 'Z';
b <= '1';
when "01" => -- output
if a = '1' then
bidir <= 'H';
else
bidir <= '0';
end if;
b <='1' ;
when "10" => -- input
bidir <= 'Z';
b <= to_X01(bidir);
when "11" =>
if a = '1' then
bidir <= 'H';
else
bidir <= '0';
end if;
--bidir <= a;
b <= to_X01(bidir);
when others =>
bidir <= 'Z';
b <= to_X01(bidir);
end case;
END PROCESS;
END logic;
Picture: https://www.alteraforum.com/forum/attachment.php?attachmentid=7713 My question is: - Is it correct to use 'H' in my code just because it does not appear right in the simulation. The RTL block diagram does not appear different between the two versions of my code. I cannot understand having a 'weak pull up' signal in the FPGA.
- I also learnt that to convert the 'H' to a 'strong' logic level of '0' or '1' I am supposed to use the to_X01() function. How is this function handled during synthesizing?