R
rickman
Guest
I was considering what it will take to implement a bi-directional
switch in VHDL and found this by Peter Ashenden. The method is pretty
much what I had thought of, but it does have one problem where a high
impedance on either side of the switch will not be conveyed to the
other once the bus has been set to a 1 or 0 state. In essence, this
is not really a switch, but rather a bus keeper.
function weaken ( value : in std_logic ) return std_logic is
type lookup_array is array (std_logic) of std_logic;
constant lookup_weaker_value : lookup_array
:= ('U'=>'U', 'X'=>'W', '0'=>'L', '1'=>'H', 'Z'=>'Z',
'L'=>'L', 'H'=>'H', 'W'=>'W', '-'=>'-');
begin
return lookup_weaker_value(value);
end function weaken;
Then we define the switch model along the following lines:
process (x, y, switch_on) is
begin
if switch_on then
x <= weaken after 250 ps;
y <= weaken(x) after 250 ps;
else
x <= 'Z' after 250 ps;
y <= 'Z' after 250 ps;
end if;
end process;
It occurred to me that the model could take advantage of the delay
spec and allow the "uncertainty" in delay of real devices to introduce
a difference in timing which could allow a Z to stabilize.
process (x, y, switch_on) is
variable old_x, old_y : std_logic;
begin
if switch_on then
if (x = old_x) then
x <= 'Z', weaken after 250 ps;
else
x <= 'Z';
end if;
old_x := x;
if (x = 'Z') then
elsif (y = old_y) then
y <= 'Z', weaken(x) after 250 ps;
else
y <= 'Z';
end if;
old_y := y;
else
x <= 'Z';
y <= 'Z';
end if;
end process;
By assigning a Z with no delay and assigning everything else with an
initial Z and a delay, I believe there will be an initial glitch and a
final state of Z when neither bus is driven. Since the behavior in
the propagation delay time is essentially an undefined state, I don't
think the intermediate Z state is any real problem.
I haven't simulated this. Any idea if I am off base here?
Rick
switch in VHDL and found this by Peter Ashenden. The method is pretty
much what I had thought of, but it does have one problem where a high
impedance on either side of the switch will not be conveyed to the
other once the bus has been set to a 1 or 0 state. In essence, this
is not really a switch, but rather a bus keeper.
function weaken ( value : in std_logic ) return std_logic is
type lookup_array is array (std_logic) of std_logic;
constant lookup_weaker_value : lookup_array
:= ('U'=>'U', 'X'=>'W', '0'=>'L', '1'=>'H', 'Z'=>'Z',
'L'=>'L', 'H'=>'H', 'W'=>'W', '-'=>'-');
begin
return lookup_weaker_value(value);
end function weaken;
Then we define the switch model along the following lines:
process (x, y, switch_on) is
begin
if switch_on then
x <= weaken after 250 ps;
y <= weaken(x) after 250 ps;
else
x <= 'Z' after 250 ps;
y <= 'Z' after 250 ps;
end if;
end process;
It occurred to me that the model could take advantage of the delay
spec and allow the "uncertainty" in delay of real devices to introduce
a difference in timing which could allow a Z to stabilize.
process (x, y, switch_on) is
variable old_x, old_y : std_logic;
begin
if switch_on then
if (x = old_x) then
x <= 'Z', weaken after 250 ps;
else
x <= 'Z';
end if;
old_x := x;
if (x = 'Z') then
elsif (y = old_y) then
y <= 'Z', weaken(x) after 250 ps;
else
y <= 'Z';
end if;
old_y := y;
else
x <= 'Z';
y <= 'Z';
end if;
end process;
By assigning a Z with no delay and assigning everything else with an
initial Z and a delay, I believe there will be an initial glitch and a
final state of Z when neither bus is driven. Since the behavior in
the propagation delay time is essentially an undefined state, I don't
think the intermediate Z state is any real problem.
I haven't simulated this. Any idea if I am off base here?
Rick