VHDL switch model

R

rickman

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(y) 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(y) 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
 
R

rickman

Another example you might want to look at is Ben Cohen's zero ohm
resistor model.

http://www.google.com/search?hl=en&rlz=1G1GGLQ_ENUS278&q="Ben+Cohen...

KJ

I may have replied too soon. I'm not sure his resistor even works.
If A and B have different values, the model will drive each bus with a
'Z' initially. Then after a delta delay each bus will be driven with
the state of the other. This will put an 'X' on each bus. This
triggers the process again and the model drives a 'Z' again. Now the
value of the bus returns to the values driven by the A and B drivers
and the process repeats. It looks to me like it will infinite loop
oscillating, just advancing delta times and never advance in real
time.

Again, a simulation is worth a thousand code reviews.

Rick
 
K

KJ

I may have replied too soon.  I'm not sure his resistor even works.
If A and B have different values, the model will drive each bus with a
'Z' initially.  Then after a delta delay each bus will be driven with
the state of the other.  This will put an 'X' on each bus.  This
triggers the process again and the model drives a 'Z' again.  Now the
value of the bus returns to the values driven by the A and B drivers
and the process repeats.  It looks to me like it will infinite loop
oscillating, just advancing delta times and never advance in real
time.

Again, a simulation is worth a thousand code reviews.

I've used Ben's model and it 'works', but only under specific sets of
conditions whether they apply to your case or not I don't know. I'll
also say that I haven't run across a model for a resistor that works
under all configurations that you would use a resistor in, I'm
guessing that the bi-directional switch that you're working on might
be just as difficult.

Some typical resistor configuration and the problems that might occur:
- Series termination. Output can't go to 'Z' even for a delta cycle
on any sort of 'clock' signal or the 'rising_edge()' VHDL function
will fail.
- Pullup and down termination (i.e. 220/330 typical). You need to
ignore the larger valued resistor.
- Differential termination (i.e. 100 ohm across a pair). You need to
totally ignore the resistor.

As a result I came up with a handful of different resistor models and
used a VHDL configuration to select the appropriate one to use. The
PCBA model was generated by a CAD system which makes the model very
accurate but then not really directly editable since it would get
overwritten every time the schematic was updated.

Kevin Jennings
 
R

Ralf Hildebrandt

rickman said:
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.


Here is my solution:
<http://www.ralf-hildebrandt.de/publication/transfergate/transfergate.vhd>
<http://www.ralf-hildebrandt.de/publication/transfergate/tbench_transfergate.vhd>

Ralf
 
R

rickman


I had taken another look at Ben's code and found something I don't
understand. I see the same thing in your code. Maybe I have
forgotten something, but I thought a process had to either have a
sensitivity list, contain a loop or it would only be run once. Both
your code and Ben's have no sensitivity list and no loop. What am I
missing here?
 
K

KJ

rickman said:
I had taken another look at Ben's code and found something I don't
understand. I see the same thing in your code. Maybe I have
forgotten something, but I thought a process had to either have a
sensitivity list, contain a loop or it would only be run once. Both
your code and Ben's have no sensitivity list and no loop. What am I
missing here?

A loop is not required. A process must contain either a sensitivity list or
a wait statement. All processes automatically 'restart' when they exit, the
only wait to have something run once is with an unconditional 'wait;' at
some point.

KJ
 
R

rickman

A loop is not required. A process must contain either a sensitivity list or
a wait statement. All processes automatically 'restart' when they exit, the
only wait to have something run once is with an unconditional 'wait;' at
some point.

KJ

Is having this statement at the beginning of the process equivalent to
using a sensitivity list (without the "until" part)?

wait on wireA'transaction, wireB'transaction, sel'transaction until
last/=now;

I am not clear on the purpose of the "until" portion. It looks to me
like it makes the process continue as soon as the "real" time
increments. Is that right? Having this run on every increment of
time seems pretty inefficient.

Does this "glitch" the bus on the delta cycles? I mean will a
simulator display continuous transitions on these signals because of
the change from driving 'Z' vs. the other bus?

I need to fire up the simulator, but I don't have time right now. But
then again, I need to use this, so maybe I don't have a choice.

Rick
 
R

Ralf Hildebrandt

rickman said:
Is having this statement at the beginning of the process equivalent to
using a sensitivity list (without the "until" part)?

Without the until-part: yes.

wait on wireA'transaction, wireB'transaction, sel'transaction until
last/=now;

I am not clear on the purpose of the "until" portion. It looks to me
like it makes the process continue as soon as the "real" time
increments. Is that right? Having this run on every increment of
time seems pretty inefficient.

The process is stopped as long as the wait-condition is not met. Then it
is run if last/=now. This makes simulation time acceptable.

I used this transfer gate to model an analog switch matrix outside of
the ASIC for testbench purpose. The ASIC controls the switches and the
testbench simulates the behavior of the other components on a PCB (the
analog switches).
Does this "glitch" the bus on the delta cycles? I mean will a
simulator display continuous transitions on these signals because of
the change from driving 'Z' vs. the other bus?

Every time the transfer gate "fires" it generates a new event - even if
the signal value does not change.


Ralf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top