EDAboard.com | EDAboard.eu | EDAboard.de | EDAboard.co.uk | RTV forum PL | NewsGroups PL

Identity-conversion of the clock signal

elektroda.net NewsGroups Forum Index - VHDL Language - Identity-conversion of the clock signal

Goto page 1, 2  Next

valentin tihhomirov
Guest

Wed Jan 20, 2010 8:43 pm   



Hello,

what if you clock one trigger by std_logic CLK and another by
to_bit(CLK)? What if another clock is to_stdulogic(to_bit(std)). We have
std-to-bit-to-std converter on the clock line in this case. Any VHDL HW
engeneer has a feeling that the conversion is redundant and will be
"optimized out" by synthesizer. In my case, the intermediate value is of
tri-valued type instead of bit, but idea is the same.

Below is the code that intermediately converts an std_logic CLK into a
multibit type and then makes an inverse conversion. The clock never
takes the 3rd value; it is just a convenient way to pass a signal from a
two-valued circuit to a multivalued one that has its clock also
multivalued for convenience. During logic optimization, synthesizer
should replace the 'doniting' converters with a plain wire; so, the
behavour must be like there is a single clock net.

To demonstrate equivalence of the original CLK and the final bitCLK, I
put two regs in pipeline and expect that the following register Q
reproduces the leading D with a single clock cycle delay. Unfortunately,
all RTL simulators I tried (Symphony, Modelthech and my favorite
Active-HDL) agree on something different: Q is fetched the same value as
D simultaneously, without the cycle shift. That is because D is updated
earlier than the clock event reaches Q (I suspect that converter delays
evaluation of clk at Q by 2 delta-cycles). Nevertheless, synthesizer
does not disappoint me: XST removes the unnecessary conversion functions
and gives the implementation the desired pipeline behaviour.

The experiment reveals that simulators 1) refuse to model the FF
behaviour (that requires to fetch the value active at reg input in the
moments preceding the CLK rising edge) 2) nor aim to predict the
synthesised HW behaviour. Nevertheless, the simulators have no
difficulty handling the widely used std-bit conversion:

bitCLK <= std_logic_1164.to_bit(stdlogicCLK);
process begin wait until bitCLK='1'; ...

It is this deceptive success of this given sample that mislead me to my
design. Can you explain why the simulators démarche in case of my
conversion?

I always have problems finding the LRM. Does it require that the sync
clocks are the same wire (not just logically identical)? I have resolved
the issue by balancing the delays (the clock of the first reg is also
null-converted) but it looks fragile and I do not understand why no
balancing is needed in case of std-bit conversion? Or I mistake and the
latter is also unreliable?


use IEEE.STD_LOGIC_1164.ALL;
entity BIST is
port (
CLK: std_logic;
Q: out std_logic
);
end entity;

architecture RTL of BIST is

type TRIVAL is ('U', '0', '1');

FUNCTION BIT_TO_TRIVAL(b: bit) return TRIVAL is -- returns TRIVAL
equivalent of bit
begin
if b = '0' then return '0';
else return '1';
end if;
end function;

signal triCLK: TRIVAL;
signal D: std_logic := '0';

begin


SQUARE_GEN: process
begin
wait until clk = '1';
D <= not D;
end process;

triCLK <= BIT_TO_TRIVAL(to_bit(CLK));

TRIVAL_CLOCKED: block
signal bitCLK: bit;
FUNCTION To_bit ( a : TRIVAL; umap : BIT := '0') RETURN BIT IS
BEGIN
CASE a IS
WHEN '0' => RETURN ('0');
WHEN '1' => RETURN ('1');
WHEN OTHERS => RETURN umap;
END CASE;
END;


begin
bitCLK <= To_bit(triCLK); -- TRIVAL clock to bit

process begin
--wait until CLK='1'; -- this is ok
wait until bitCLK='1'; -- this causes problems
Q <= D;
end process;
end block;

end RTL;



library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity BIST_TB is
end entity;

architecture BEH of BIST_TB is
signal CLK: std_logic := '0';
begin
process begin
loop
CLK <= not CLK; wait for 50 ns;
end loop;
end process;

BIST_U: entity work.BIST
port map(CLK);

end architecture;


Thank you for participation.

Brian Drummond
Guest

Thu Jan 21, 2010 2:18 am   



On Wed, 20 Jan 2010 21:43:07 +0200, valentin tihhomirov <nospam_at_server.org>
wrote:

Quote:
Hello,

what if you clock one trigger by std_logic CLK and another by
to_bit(CLK)? What if another clock is to_stdulogic(to_bit(std)). We have
std-to-bit-to-std converter on the clock line in this case. Any VHDL HW
engeneer has a feeling that the conversion is redundant and will be
"optimized out" by synthesizer. In my case, the intermediate value is of
tri-valued type instead of bit, but idea is the same.


The conversions don't matter - either in synthesis or simulation.

The signal assignments do.

You can rewrite this with the same type throughout for your intermediate clock
signals - no conversions - and it will do the same. Try it.

The simulators are effectively modelling what you wrote as a race condition and
alerting you that this code gives a likelihood of clock skew. In other words,
they are correct.

You are lucky that XST implemented it as you expect; it could have decided to
insert a clock buffer between "clk" and "bitCLK" and then what would happen?
(XST probably won't ... though different XST versions have put clock buffers in
different places in the past ... but what about other tools?)

Quote:
I always have problems finding the LRM. Does it require that the sync
clocks are the same wire (not just logically identical)?

The LRM doesn't, but good design practice does. Generate the clock; then use the
same clock for both the producer and consumer (of D in this example).

- Brian.

valentin tihhomirov
Guest

Thu Jan 21, 2010 4:46 pm   



Thank you for response.


Quote:
The conversions don't matter - either in synthesis or simulation.
The signal assignments do. You can rewrite this with the same type
throughout for your intermediate clock signals - no conversions -
and it will do the same. Try it.

Your are right. I've checked that and confirm that these are the
assignmnents rather than conversion or non-std logic that create the
skew problem. It is unbelivable since the assignment looks as a plain
conductor, which is a way simpler than the multilevel conversion, which
is so complex that you may not even recognize the trivial identity
operation in it.


Quote:
The simulators are effectively modelling what you wrote as a race condition and
alerting you that this code gives a likelihood of clock skew. In other words,
they are correct.


Unfortunately, they do not alert. XST sometimes does but not in this case.


Quote:
You are lucky that XST implemented it as you expect; it could have decided to
insert a clock buffer between "clk" and "bitCLK" and then what would happen?
(XST probably won't ... though different XST versions have put clock buffers in
different places in the past ... but what about other tools?)

I think all synthesizers are the same: they all do logical optimization.
And, if they put a buffer, they know that logic is identical.
Actually, I believe that they always put buffers on the clock -- it is
so large and what will happen if they do not put the buffers Wink The
proper buffer placement is FPGA supplier concern.



Quote:
I always have problems finding the LRM. Does it require that the sync
clocks are the same wire (not just logically identical)?

The LRM doesn't, but good design practice does.
Generate the clock; then use the same clock for both
the producer and consumer (of D in this example).

Thank you. Unfortunately, there are the cases where the clock passes
through a block of non-standard logic, like it does in mine case. And,
shouldn't it be the LRM that tells us what the good design practice is?

valentin tihhomirov
Guest

Thu Jan 21, 2010 5:42 pm   



I was surprised to know that it is the assignment rather than conversion
that causes the simulation clock skew. It is furthermore surprising when
I think of instantiation. The port mapping looks very much like
assigning signals to I/O. Yet, the unbalanced depth hierarchies are not
known to cause the clock skew.

Jonathan Bromley
Guest

Thu Jan 21, 2010 6:00 pm   



On Thu, 21 Jan 2010 18:42:56 +0200, valentin tihhomirov
<nospam_at_server.org> wrote:

Quote:
I was surprised to know that it is the assignment rather than conversion
that causes the simulation clock skew. It is furthermore surprising when
I think of instantiation. The port mapping looks very much like
assigning signals to I/O. Yet, the unbalanced depth hierarchies are not
known to cause the clock skew.

AAAAAARGH!!!!!!!!!!!!

Yes, your "discovery" is correct, and in fact is a very
fundamental idea in VHDL: when you connect a signal to
a port, the signal OUTSIDE the port and the signal
INSIDE the port are completely merged, and become
one and the same signal.

This is true even if there is a type conversion in the
port map.

This identity of signals on either side of a port
makes it possible, for example, to detect and use
the 'TRANSACTION attribute of a signal in a different
module than that containing the driver.

It is an important difference between VHDL and
Verilog; in Verilog, a unidirectional port generally
looks like a continuous assignment (a buffer) across
the module boundary. Bidirectional ports in Verilog
are merged, just as in VHDL. Unfortunately it's
not that simple, because simulators are entitled
to merge unidirectional ports as an optimization.
Luckily this does not lead to impossible skew
problems, because the buffer delay in Verilog is
actioned earlier than the nonblocking assignment
delay that is normally used for flipflops.

HOWEVER.................

under pressure from <insert names of your enemies here>
VHDL 2008 has permitted expressions in port maps, and
such expressions DO create a delta-cycle delay across
the port. Personally I regard this as a very misguided
move, breaking an important and elegant feature of the
language for the sake of a trivial improvement in
convenience for some kinds of RTL design. But that
is a completely different rant, for another day...
--
Jonathan Bromley
--
Jonathan Bromley, Verification Engineer

Verilab www.THAT_COMPANY.com

valentin tihhomirov
Guest

Thu Jan 21, 2010 7:32 pm   



Jonathan Bromley wrote:
Quote:
On Thu, 21 Jan 2010 18:42:56 +0200, valentin tihhomirov
nospam_at_server.org> wrote:

I was surprised to know that it is the assignment rather than conversion
that causes the simulation clock skew. It is furthermore surprising when
I think of instantiation. The port mapping looks very much like
assigning signals to I/O. Yet, the unbalanced depth hierarchies are not
known to cause the clock skew.

AAAAAARGH!!!!!!!!!!!!

Yes, your "discovery" is correct, and in fact is a very
fundamental idea in VHDL: when you connect a signal to
a port, the signal OUTSIDE the port and the signal
INSIDE the port are completely merged, and become
one and the same signal.

This is true even if there is a type conversion in the
port map.

This identity of signals on either side of a port
makes it possible, for example, to detect and use
the 'TRANSACTION attribute of a signal in a different
module than that containing the driver.

It is an important difference between VHDL and
Verilog; in Verilog, a unidirectional port generally
looks like a continuous assignment (a buffer) across
the module boundary. Bidirectional ports in Verilog
are merged, just as in VHDL. Unfortunately it's
not that simple, because simulators are entitled
to merge unidirectional ports as an optimization.
Luckily this does not lead to impossible skew
problems, because the buffer delay in Verilog is
actioned earlier than the nonblocking assignment
delay that is normally used for flipflops.

HOWEVER.................

under pressure from <insert names of your enemies here
VHDL 2008 has permitted expressions in port maps, and
such expressions DO create a delta-cycle delay across
the port. Personally I regard this as a very misguided
move, breaking an important and elegant feature of the
language for the sake of a trivial improvement in
convenience for some kinds of RTL design. But that
is a completely different rant, for another day...


One of the "enemies" desired the expressions was me:
http://groups.google.ee/group/comp.lang.vhdl/browse_thread/thread/54964f76d0b64cc2
and
http://groups.google.ee/group/comp.lang.vhdl/browse_thread/thread/244b103de6179efa

Yet, my confusion goes deeper as VHDL experts tell the strange things
like expressions must incur a delay (why?) if Brain just pointed out
that the conversions do not impose any. May be it is appropriate place
to inform the reader that I have resolved my problem by using

wait until multivaluedCLK = '1';

construction. It is considerably more concise and less fragile than
keeping the balancing the assignments.

Jonathan Bromley
Guest

Thu Jan 21, 2010 7:55 pm   



On Thu, 21 Jan 2010 10:09:52 -0800 (PST), Andy wrote:

Quote:
How does a pre-2008 port type conversion function execute without a
delta delay? How are events passed from the one type to the other
without a delta between them?

Well... if asked to hazard a guess, I'd say that...
- on input, the signal inside the module is rewritten to be
of the "outside" type, and all readers inside the module
get the incoming conversion automatically applied;
- on output, the signal inside is likewise rewritten to be
of the "outside" type, and the value presented by each
driver inside the module automatically suffers the outgoing
conversion before being applied to the signal.
In this way, events pass through unharmed but values are mapped.

Quote:
What if one or both types are resolved types?
See above; the conversion can be per-reader and per-writer.

I don't actually know, but I guess on output the inside type's
resolution function could be applied to all the inside drivers,
and then the result converted before being sent to the outside
type's resolution function.

Quote:
I was pretty sure that the Pre-2008 port conversions incurred a delta
delay,

You panicked me with your post, so I tried it just to be sure.
Try this... the signal assignment incurs a delta delay (of course)
and so you see differences between s_bo and p_bo, but the
converted port p_bi and unconverted p_bo always match.
And it's a custom conversion function :-0

package p is
function to_bit(b: boolean) return bit;
end;

package body p is
function to_bit(b: boolean) return bit is
begin
if b then return '1'; else return '0'; end if;
end;
end;

use work.p.all;
entity e is
port (p_bi: in bit; p_bo: in boolean);
end;
architecture a of e is
signal s_bo: boolean;
begin
s_bo <= p_bo;
process(p_bi, p_bo)
begin
if p_bi = to_bit(p_bo) then
report "OK: " & bit'image(p_bi) & ", " & boolean'image(p_bo);
else
report "??: " & bit'image(p_bi) & ", " & boolean'image(p_bo);
end if;
end process;
process(s_bo, p_bo)
begin
if s_bo = p_bo then
report "OK: " & boolean'image(s_bo) & ", " &
boolean'image(p_bo);
else
report "??: " & boolean'image(s_bo) & ", " &
boolean'image(p_bo);
end if;
end process;
end;

use work.p.all;
entity tb is end;
architecture a of tb is
signal b: boolean;
begin
b <= TRUE after 1 ns, FALSE after 2 ns, TRUE after 3 ns;
test: entity work.e port map (p_bi => to_bit(b), p_bo => b);
end;

--
Jonathan Bromley
--
Jonathan Bromley, Verification Engineer

Verilab www.THAT_COMPANY.com

Andy
Guest

Thu Jan 21, 2010 8:09 pm   



On Jan 21, 11:00 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
Quote:
under pressure from <insert names of your enemies here
VHDL 2008 has permitted expressions in port maps, and
such expressions DO create a delta-cycle delay across
the port.  Personally I regard this as a very misguided
move, breaking an important and elegant feature of the
language for the sake of a trivial improvement in
convenience for some kinds of RTL design.  But that
is a completely different rant, for another day...
--
Jonathan Bromley

Jonathan,

How does a pre-2008 port type conversion function execute without a
delta delay? How are events passed from the one type to the other
without a delta between them?

What if one or both types are resolved types?

I was pretty sure that the Pre-2008 port conversions incurred a delta
delay, but I could very easily be wrong about that... I could see how
an implicit conversion between similar types (e.g. unsigned <-> SLV, a
"cast") could work without a delta, but not an arbitrary, explicit
conversion function (e.g. SL to boolean).

Andy

Andy
Guest

Thu Jan 21, 2010 9:37 pm   



On Jan 21, 12:55 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
Quote:
On Thu, 21 Jan 2010 10:09:52 -0800 (PST), Andy wrote:
How does a pre-2008 port type conversion function execute without a
delta delay? How are events passed from the one type to the other
without a delta between them?

Well... if asked to hazard a guess, I'd say that...
  - on input, the signal inside the module is rewritten to be
    of the "outside" type, and all readers inside the module
    get the incoming conversion automatically applied;
  - on output, the signal inside is likewise rewritten to be
    of the "outside" type, and the value presented by each
    driver inside the module automatically suffers the outgoing
    conversion before being applied to the signal.
In this way, events pass through unharmed but values are mapped.

What if one or both types are resolved types?

See above; the conversion can be per-reader and per-writer.
I don't actually know, but I guess on output the inside type's
resolution function could be applied to all the inside drivers,
and then the result converted before being sent to the outside
type's resolution function.

I was pretty sure that the Pre-2008 port conversions incurred a delta
delay,

You panicked me with your post, so I tried it just to be sure.
Try this...  the signal assignment incurs a delta delay (of course)
and so you see differences between s_bo and p_bo, but the
converted port p_bi and unconverted p_bo always match.
And it's a custom conversion function :-0

package p is
  function to_bit(b: boolean) return bit;
end;

package body p is
  function to_bit(b: boolean) return bit is
  begin
    if b then return '1'; else return '0'; end if;
  end;
end;

use work.p.all;
entity e is
  port (p_bi: in bit; p_bo: in boolean);
end;
architecture a of e is
  signal s_bo: boolean;
begin
  s_bo <= p_bo;
  process(p_bi, p_bo)
  begin
    if p_bi = to_bit(p_bo) then
      report "OK: " & bit'image(p_bi) & ", " & boolean'image(p_bo);
    else
      report "??: " & bit'image(p_bi) & ", " & boolean'image(p_bo);
    end if;
  end process;
  process(s_bo, p_bo)
  begin
    if s_bo = p_bo then
      report "OK: " & boolean'image(s_bo) & ", " &
boolean'image(p_bo);
    else
      report "??: " & boolean'image(s_bo) & ", " &
boolean'image(p_bo);
    end if;
  end process;
end;

use work.p.all;
entity tb is end;
architecture a of tb is
  signal b: boolean;
begin
  b <= TRUE after 1 ns, FALSE after 2 ns, TRUE after 3 ns;
  test: entity work.e port map (p_bi => to_bit(b), p_bo => b);
end;

--
Jonathan Bromley
--
Jonathan Bromley, Verification Engineer

Verilab  www.THAT_COMPANY.com

Fair enough; thanks for the explanation!

"Learn something new every day."

Andy

Jonathan Bromley
Guest

Fri Jan 22, 2010 1:24 am   



On Thu, 21 Jan 2010 11:37:53 -0800 (PST), Andy wrote:

Quote:
"Learn something new every day."

I try; honestly, I try. But as I get older, the
learning process becomes less comfortable.
Increasingly I depend on the youngsters to keep
me honest and to show me the places I still need
to learn more...
--
Jonathan Bromley
--
Jonathan Bromley, Verification Engineer

Verilab www.THAT_COMPANY.com

Jonathan Bromley
Guest

Fri Jan 22, 2010 1:31 am   



On Thu, 21 Jan 2010 20:32:07 +0200, valentin tihhomirov wrote:

Quote:
Yet, my confusion goes deeper as VHDL experts tell the
strange things like expressions must incur a delay (why?)

Expressions *in a port map* incur a delta delay, because
the port map

instance: some_component port map (e_port => expression, ...);

is equivalent to

temp_signal <= expression; -- here is the delta delay
instance: some_component port map (e_port => temp_signal, ...);

Note that the delay is caused by the signal assignment -
it is NOT caused by the expression itself. An expression
is merely a calculation and it takes place in zero time,
without a delta delay.

Quote:
I have resolved my problem by using

wait until multivaluedCLK = '1';

How is this different from any other way of
sensing an event on multivalueCLK ???
--
Jonathan Bromley
--
Jonathan Bromley, Verification Engineer

Verilab www.THAT_COMPANY.com

valentin tihhomirov
Guest

Fri Jan 22, 2010 6:01 pm   



Quote:
Note that the delay is caused by the signal assignment -
it is NOT caused by the expression itself. An expression
is merely a calculation and it takes place in zero time,
without a delta delay.

Yes, I see but it is not obvious that expressions infere an assignement.
And, I still haven't got any explanation why the hell a simple
assignment, a data movment operator that infers no more than a wire,
takes a way more time to simulate while a conversion, the data
processing, which inevitably involves the data movement, takes zero time?


Quote:

I have resolved my problem by using

wait until multivaluedCLK = '1';

How is this different from any other way of
sensing an event on multivalueCLK ???

Excuse me, the point was that VHDL allows to wait for event on
non-standard logic. This is an enabler to the assigment-free approach.
The style of sensing does not matter.

One of the blocks in my design is custom logic based: all its signals
including clock are multivalued. This block is a netlist that passes its
multivalued CLK to flip-flop primitives. Originally, the netlist was
std_logic-based and FF primitives used the following construction:

BitClk <= to_bit(CLK);
process begin
wait until BitClk = '1';

I obtained it from academia withoug any skew problems. I, therefore,
started to think this is a proper VHDL style. It also served me as a
hint to go with multivalued logic -- just define a function to convert
from a custom type to bit and get a multivalued-clock controlled
register (clock uses only two values). Suddenly, my conversion produced
the skew problem. I initially believed, it is due to custom conversion
because to_bit(std) revealed no problem. Then, Brain explained that the
assignments are the source of skew and proposed a single clock net as a
"good design practice". Since it is difficult in my case to pass
std_logic through a custom-type CUT, I first decided to balance the
conversions. It is verbose and fragile to care that all regs have
balanced clock assignments. I have also realized that there are
hierarchial ports on the way. The port mappings also looks like an
assignment and promises the same probelm. Fortunately, this discussion
has revealed that the zero-delay port mapping and conversion allow to
accomplish without the detrimental assignments. It would not be possible
though if VHDL forbided the wait for custom logic event.

Jonathan Bromley
Guest

Fri Jan 22, 2010 6:38 pm   



On Fri, 22 Jan 2010 19:01:48 +0200, valentin tihhomirov wrote:

Quote:
Note that the delay is caused by the signal assignment -
it is NOT caused by the expression itself. An expression
is merely a calculation and it takes place in zero time,
without a delta delay.

Yes, I see but it is not obvious that expressions infere an assignement.

I'm not quite sure what you mean here - expressions don't
themselves imply an assignment. The exception is the new
syntax allowing an expression in a port map:

instance: thing port map (input => (A and B), ...

is the same as

temp_signal <= A and B;
instance: thing port map (input => temp_signal, ...

which, of course, introduces a delta delay thanks to
the implicit signal assignment to temp_signal.

Quote:
And, I still haven't got any explanation why the hell a simple
assignment, a data movment operator that infers no more than a wire,
takes a way more time to simulate while a conversion, the data
processing, which inevitably involves the data movement, takes zero time?

We're talking about simulated time here. VHDL has strict
update/execute semantics: whenever a <= signal assignment is
executed, the updating of the target signal is postponed
until the update phase - after all processes have finished
their currently-running execute phase and have reached a
wait of some kind. That's why VHDL does not suffer the
absurd read/write races that plague Verilog. Variable
assignments, however, occur inline during the execute
phase, in zero simulated time no matter how complex the
calculation.

Quote:
I have resolved my problem by using

wait until multivaluedCLK = '1';

How is this different from any other way of
sensing an event on multivalueCLK ???

Excuse me, the point was that VHDL allows to wait for event on
non-standard logic. This is an enabler to the assigment-free approach.
The style of sensing does not matter.

One of the blocks in my design is custom logic based: all its signals
including clock are multivalued. This block is a netlist that passes its
multivalued CLK to flip-flop primitives. Originally, the netlist was
std_logic-based and FF primitives used the following construction:

BitClk <= to_bit(CLK);
process begin
wait until BitClk = '1';

I obtained it from academia withoug any skew problems.

That was luck rather than good academia, as I'm sure you
now are aware. Any delta delay on a clock net can easily
give rise to skew trouble.

Note, however, that even this can easily be rewritten to
avoid the assignment's delta-skew:

process begin
wait until to_bit(CLK) = '1';

And, once again, this solution is correct no matter how
complicated the conversion function might be. Indeed,
the common synthesis idiom
rising_edge(clock)
is just such a conversion function, evaluating a boolean
based on the current and immediately previous value of
the std_logic clock.

Quote:
Since it is difficult in my case to pass
std_logic through a custom-type CUT, I first decided to balance the
conversions. It is verbose and fragile to care that all regs have
balanced clock assignments.

Indeed - close to impossible in practice, I guess.
Of course, ASIC place-and-route tools must necessarily
do precisely that, by constructing appropriate clock
distribution networks - but that is a very different problem.

Quote:
I have also realized that there are
hierarchial ports on the way. The port mappings also looks like an
assignment and promises the same probelm. Fortunately, this discussion
has revealed that the zero-delay port mapping and conversion allow to
accomplish without the detrimental assignments.

Hierarchical design of synchronous logic would be miserably
difficult if this were not so.

Sometimes, however, the needs of modelling mean that you
will be forced into having some delta delay on your clock.
Although this is tiresome, and it has caused many people
(including me) some trouble, it is possible to deal with it.

There is an alternative approach which is much less fragile.
For every synchronous (registered) output from any block,
introduce a small time delay. This models the flipflops'
clock to output delay, and ensures enough hold time for
other flipflops that use the same clock even if their
clock has a delta delay. It is easy to add a time delay
in a signal assignment from the block's internal signal
to its output port:

entity shifter is
port (clk: in std_logic; d: in std_logic; q: out std_logic);
end;
architecture two_stage of shifter is
signal shift_register: std_logic_vector(0 to 1);
begin
process (clk) begin
if rising_edge(clk) then
shift_register <= d & shift_register(0);
end if;
end process;

-- This assignment models clock-to-output delay
-- and provides enough hold time for other flops
-- even if their clock is delayed by many delta cycles
q <= shift_register(1) after 100 ps;
end;

--
Jonathan Bromley

valentin tihhomirov
Guest

Sat Jan 23, 2010 9:20 pm   



Quote:
I'm not quite sure what you mean here - expressions don't
themselves imply an assignment. The exception is the new
syntax allowing an expression in a port map:

instance: thing port map (input => (A and B), ...

is the same as

temp_signal <= A and B;
instance: thing port map (input => temp_signal, ...

which, of course, introduces a delta delay thanks to
the implicit signal assignment to temp_signal.


This helped me to understand that the words "to imply" and "implicit"
are relative, that they have a common root. I've got that despite you
use them contradictively. Do you see that you first denounce the
implication and then reannounce it again?


Quote:
And, I still haven't got any explanation why the hell a simple
assignment, a data movment operator that infers no more than a wire,
takes a way more time to simulate while a conversion, the data
processing, which inevitably involves the data movement, takes zero time?

We're talking about simulated time here. VHDL has strict
update/execute semantics: whenever a <= signal assignment is
executed, the updating of the target signal is postponed
until the update phase - after all processes have finished
their currently-running execute phase and have reached a
wait of some kind. That's why VHDL does not suffer the
absurd read/write races that plague Verilog. Variable
assignments, however, occur inline during the execute
phase, in zero simulated time no matter how complex the
calculation.


Why to use assignments to bring some order into the evaluation logic if
you admit yourself that it is almost impossible in practice to rely on
it? IMO, assignments exist in all languages for one important thing: you
compute once and save/share the result.

The benefit of manually inserting the trigger hold delay is that you do
it almost thoughtlessly. But doing it per every FF is also quite
tiresome. Doing this automatically by simulators is what I desired
complaining their discrepancy from HW.


Quote:
I have resolved my problem by using

wait until multivaluedCLK = '1';
How is this different from any other way of
sensing an event on multivalueCLK ???
Excuse me, the point was that VHDL allows to wait for event on
non-standard logic. This is an enabler to the assigment-free approach.
The style of sensing does not matter.

One of the blocks in my design is custom logic based: all its signals
including clock are multivalued. This block is a netlist that passes its
multivalued CLK to flip-flop primitives. Originally, the netlist was
std_logic-based and FF primitives used the following construction:

BitClk <= to_bit(CLK);
process begin
wait until BitClk = '1';

I obtained it from academia withoug any skew problems.

That was luck rather than good academia, as I'm sure you
now are aware. Any delta delay on a clock net can easily
give rise to skew trouble.

Note, however, that even this can easily be rewritten to
avoid the assignment's delta-skew:

process begin
wait until to_bit(CLK) = '1';


This is indeed an alternative to waiting on custom logic. Unfortunately,
none besides 'academic style' is supported by XST, as experiments show
http://forums.xilinx.com/xlnx/board/message?board.id=SYNTHBD&thread.id=1747

KJ
Guest

Sun Jan 24, 2010 12:13 am   



Quote:

Why to use assignments to bring some order into the evaluation logic if
you admit yourself that it is almost impossible in practice to rely on
it? IMO, assignments exist in all languages for one important thing: you
compute once and save/share the result.


You're correct that one uses a concurrent signal assignment or a
variable assignment as a method to save (*1) a result to be used by
something else. The reason for doing this is to improve code
maintainability. It can also help with debug of the code when there
is a clear (and correct) match between the naming of the signal and
what it logically really represents.

Where I differ with you is when you say "almost impossible in practice
to rely on it". Rely on it to do what? The "HD" in VHDL does stand
for 'hardware description', but that does not necessarily imply that
source code literally describes the precise implementation. If it
did, then one would expect the source code that someone writes to
describe functionality by instantiating look up tables (and defining
their contents), flip flops and whatever other primitives are
available in a particular FPGA. That description would be completely
useless and have to be completely re-written to use and/or arrays and
flops if targetting a CPLD type device. Both of those descriptions
would also be completely useless if the target implementation was
discrete logic parts.

So one must accept the paradox that the hardware that is being
described in the original source code is most likely NOT a description
of the actual implemented hardware. What is the point of a 'hardware
description' language that is typically not used by an end user to
describe the actual hardware implementation? In a word,
'productivity'. Having to change source code to describe different
physical implementations (i.e. targetting different types of devices)
is not as productive as describing a mythical hardware implementation
and then using tools to translate that into something that is
physically realizable in multiple forms.

Given that the original source describes mythical and not necessarily
real hardware, one has to consider what is the purpose of the various
tools that one will use to interpret that source code. Here you seem
to be thinking that the simulator should be simulating an actual
hardware description and if an assignment will end up resulting in no
hardware, just a wire connection, then there should be no simulation
induced delay. But the simulator is simulating the description of the
mythical hardware (i.e. what is actually in the source code). The
translation of the mythical hardware description into a description of
actual hardware is the job of a synthesis tool. Those are two
independent paths.

Both synthesis and simulation are acting on the same source code
input, but performing completely different functions. Simulation
shows you what will occur if you were to build the mythical hardware
as literally described in the source code. Synthesis cobbles together
a functional near equivalent to the source code description using only
the primitives that it has available to it. The fork in the road is
that the two tools are performing completely different functions on
the same input so expecting them to behave in some coordinated manner
is not a realistic expectation.

Understanding just what different tools are trying to accomplish and
how one should then write source code so that each tool can do their
job and you can use the tools to effectively produce the intended
design and be confident that the results from both tools are valid is
important. One can describe things in source code that truly are
mythical and can not be physically realized...but that's not a fault
of the language, that's the fault of the person who thinks it could be
synthesized in the first place...but it will simulate just fine
regardless. Engineers know how to use tools in a manner that results
in a description that can be used by someone else to actually build
something.

Quote:
The benefit of manually inserting the trigger hold delay is that you do
it almost thoughtlessly. But doing it per every FF is also quite
tiresome. Doing this automatically by simulators is what I desired
complaining their discrepancy from HW.


This added delay is just a hack that in certain situations may have
some merit...nothing more.

Quote:
process begin
wait until to_bit(CLK) = '1';

This is indeed an alternative to waiting on custom logic. Unfortunately,
none besides 'academic style' is supported by XST,

Each tool has it's own unique constraints. You either live within
those constraints or don't use that tool. Those constraints also
change over time. Generally speaking, those changes over time are for
the better (i.e. simulators support updated standards, synthesis tools
accept more abstract descriptions than they used to). Each tool has
known as well as undiscovered bugs at any point in time.

Kevin Jennings

(*1): In this context, 'save' does not mean physical memory storage.

Goto page 1, 2  Next

elektroda.net NewsGroups Forum Index - VHDL Language - Identity-conversion of the clock signal

Arabic versionBulgarian versionCatalan versionCzech versionDanish versionGerman versionGreek versionEnglish versionSpanish versionFinnish versionFrench versionHindi versionCroatian versionIndonesian versionItalian versionHebrew versionJapanese versionKorean versionLithuanian versionLatvian versionDutch versionNorwegian versionPolish versionPortuguese versionRomanian versionRussian versionSlovak versionSlovenian versionSerbian versionSwedish versionTagalog versionUkrainian versionVietnamese versionChinese version
RTV map EDAboard.com map News map EDAboard.eu map EDAboard.de map EDAboard.co.uk map Opony