Is this legal?

V

Valentin Tihomirov

architecture ARCH orRX_UNIT is
signal BitPos: integer range 0 to 10;
begin

SAMPLING : process(CLK)
begin
if Rising_Edge(CLK) then
BitPos <= BitPos + 1; -- increase by default
if BitPos = 10 then -- stop bit
BitPos <= 0;
DONE <= '1'; -- signal available data
else
DATA[BitPos] <= Rx; -- store data bit
end if;
end process;

end ARCH;


Simulator stops complaining about that string where BitPos is incremented.
In fact, the logic is a bit more complex and using this style with default
assertion is very convenient. What are the problems inherent to the
situation where 11 is calculated to be written into variable that can only
keep vales in range 0..10? The calculated value 11 is ignored in any case.
 
P

Peter Molesworth

architecture ARCH orRX_UNIT is
signal BitPos: integer range 0 to 10;
begin

SAMPLING : process(CLK)
begin
if Rising_Edge(CLK) then
BitPos <= BitPos + 1; -- increase by default
if BitPos = 10 then -- stop bit
BitPos <= 0;
DONE <= '1'; -- signal available data
else
DATA[BitPos] <= Rx; -- store data bit
end if;
end process;

end ARCH;


Simulator stops complaining about that string where BitPos is
incremented.
In fact, the logic is a bit more complex and using this style with
default
assertion is very convenient. What are the problems inherent to the
situation where 11 is calculated to be written into variable that can
only
keep vales in range 0..10? The calculated value 11 is ignored in any
case.

Hi Valentin,

The only things I can say about the above is that when BitPos = 10 you are
assigning a value to BitPos in two places simmultaneously. In this case it
dosen't really matter as the assignment BitPos <= BitPos + 1 will result
in a value of 0 anyway and not 11. If you had not specified a range when
you declared BitPos you would have a the problem of the signal have two
drivers of a different value. The other thing to note is that DONE and
DATA are only assigned in one half of the second IF statement and
therefore latches are inferred. Other than that it's basically okay. Also
you probably should have a reset signal to initialise BitPos to a known
value. Depending on your target device registers may initialize to a known
value or they may be undefined. To summarise I would have written the
process as follows:

SAMPLING : process (nReset, Clk)
begin
if (nReset = '0') then
BitPos <= 0;
DONE <= '0';
DATA <= (others => '0');
elsif rising_edge (Clk) then
BitPos <= BitPos + 1;
if (BitPos = 10) then
DONE <= '1';
DATA <= DATA;
else
DONE <= DONE;
DATA[BitPos] <= Rx;
end if;
end if;
end process;

Note that in the above the DATA assignment in the second half of the IF
statement only assigns to one element of DATA so latches are inferred on
the others bits. I personally don't like inferred latches but in this case
it is okay and is the most elegant way of doing it.

I hope this has been of some use to you.

Cheers,

Pete.
 
M

Mike Treseler

Valentin said:
Simulator stops complaining about that string where BitPos is incremented.
In fact, the logic is a bit more complex and using this style with default
assertion is very convenient.

With a signal, it doesn't matter if you put

BitPos <= BitPos + 1;

before or after the limit check.
The value tested is from the previous loop.

I find that using process variables to
mold values makes the logic more understandable.

also

DATA[BitPos] <= Rx;

ought to be inside the clk clause.
Nothing should be in the else clause.
What are the problems inherent to the
situation where 11 is calculated to be written into variable that can only
keep vales in range 0..10?

The simulator will enforce your limits.
Why not use unsigned(3 downto 0) or the range 0 to 15.
At least four bits will be synthesized in any case.

-- Mike Treseler
 
V

Valentin Tihomirov

Thanks for the attempt to help me.

1. If I assign a signal inside synchonized section I do not surprise getting
flip-flop. Using default values lets to avoid many assignment statemnts in
the complex branching. It is the first lesson of VHDL class.

2. The second lesson learns that assignments inside process are not
concurrent, they are serial as opposed to concurrent blocks.

3. I could not understand the correct way of dealing with BitPos counter in
my example. How can I highlight that the register is intended to hold values
only in range 0 to 10. And what goes on when 11 is asserted to NEXT_VALUE
but is never asserted to the value? This is a corner situation.
 
P

Peter Molesworth

Thanks for the attempt to help me.

1. If I assign a signal inside synchonized section I do not surprise
getting
flip-flop. Using default values lets to avoid many assignment statemnts
in
the complex branching. It is the first lesson of VHDL class.

Yes I agree that this makes the vhdl much neater rather than having to
explicitly declare all other assignments. The only reason I try to avoid
inferred latches is to stop warnings from the synthesis tool. I find that
if there are loads of warnings about inferred latches it is easy to miss a
real warning that I should be concerned about. Sorry if I came across as
telling you stuff you already knew, that was not my intention.
2. The second lesson learns that assignments inside process are not
concurrent, they are serial as opposed to concurrent blocks.

3. I could not understand the correct way of dealing with BitPos counter
in
my example. How can I highlight that the register is intended to hold
values
only in range 0 to 10. And what goes on when 11 is asserted to NEXT_VALUE
but is never asserted to the value? This is a corner situation.

As you have declared BitPos with a range 0 to 10 the simulator will do the
range checking for you so you need not worry about it. An assertion to 11
will not occur as it will automatically wrap the value back to 0. For
synthesis you will end up with a 4-bit counter which can have a range 0 to
15. The synthesis tool will know from your type declaration that 11 to 15
are not allowed values and will generate additional logic in the counter
to rollover once 10 is reached. If you want to make it explicit anyway
then the example I provided can be modified by simply moving the
assignment to BitPos into the second IF statement. so my example would
become:

SAMPLING : process (nReset, Clk)
begin
if (nReset = '0') then
BitPos <= 0;
DONE <= '0';
DATA <= (others => '0');
elsif rising_edge (Clk) then
if (BitPos >= 10) then
BitPos <= 0;
DONE <= '1';
DATA <= DATA;
else
BitPos <= BitPos + 1;
DONE <= DONE;
DATA[BitPos] <= Rx;
end if;
end if;
end process;

I hope this is what you are after.

Cheers,

Pete.
 
C

Colin Marquardt

Peter Molesworth said:
if (BitPos >= 10) then
BitPos <= 0;
[...]

Or, even nicer,
if (BitPos >= BitPos'high) then
BitPos <= BitPos'low; -- if this is what's wanted

Cheers,
Colin
 
P

Peter Molesworth

if (BitPos >= 10) then
BitPos <= 0;
[...]

Or, even nicer,
if (BitPos >= BitPos'high) then
BitPos <= BitPos'low; -- if this is what's wanted

Cheers,
Colin

Yes very good point. I do use this technique myself as it can make
maintaining things much easier as there will be less parts of the code to
change if the range of something needs to change.

Cheers,

Pete.
 
P

Paul Uiterlinden

Peter said:
if (BitPos >= 10) then
BitPos <= 0;
[...]

Or, even nicer,
if (BitPos >= BitPos'high) then
BitPos <= BitPos'low; -- if this is what's
wanted

Cheers,
Colin

Yes very good point. I do use this technique myself as it can make
maintaining things much easier as there will be less parts of the
code to change if the range of something needs to change.

Indeed. Less "magical numbers" is better.

But the example won't work: the attributes 'high and 'low only are
allowed types and arrays. So the example should be something like
this:

SUBTYPE BitPos_type IS integer RANGE 0 TO 10;
...
IF BitPos >= BitPos_type'HIGH THEN
BitPos <= BitPos_type'LOW;

Paul.
 
V

Valentin Tihomirov

DATA[BitPos] <= Rx;

ought to be inside the clk clause.
Nothing should be in the else clause.

Why to mention this? It is inside clk.



The simulator will enforce your limits.

I understand that it inforces. I wait anyone who explains me which limits it
enforces. I never assign 11 to the variable.I just intend but I have a logic
to refuse this assignment. That is why I think my code is right.



Why not use unsigned(3 downto 0) or the range 0 to 15.
At least four bits will be synthesized in any case.

-- Mike Treseler

Curious to know a well.
 
V

Valentin Tihomirov

As you have declared BitPos with a range 0 to 10 the simulator will do the
range checking for you so you need not worry about it.

I do worry because ModelSim does. It abandons simulation alerting that 11
cannot be assigned to BitPos. This also means that no aoutomatic rollback
from 10 to 0 is generated. Therefore, these your words are not true and
making the wrap explicit makes sense.
 
M

Mike Treseler

Valentin said:
DATA[BitPos] <= Rx;

ought to be inside the clk clause.
Nothing should be in the else clause.


Why to mention this? It is inside clk.

You're right. Sorry.

I understand that it inforces. I wait anyone who explains me which limits it
enforces. I never assign 11 to the variable.I just intend but I have a logic
to refuse this assignment. That is why I think my code is right.

You can answer this question yourself just by running
a simulation and looking at the waveform values.

You might find that:

if BitPos = 10 then -- stop bit

is comparing the value that existed at
the previous clock so that the you end
up off by one on your limit.

Try it and see.

-- Mike Treseler
 
P

Peter Molesworth

I understand that it inforces. I wait anyone who explains me which
limits it
enforces. I never assign 11 to the variable.I just intend but I have a
logic
to refuse this assignment. That is why I think my code is right.

Valentin,

That will teach me to try and answer a post too quickly! I just simulated
your code sample in modelsim and I now see why you are asking the question
again. Your absolutely right, your assignment BitPos <= BitPos + 1 does
cause it to go wrong in the simulation. The reason for this is that when
the value of BitPos is 10 the "Next Cycle" value calculated becomes out of
the range of BitPos as the result is just an integer so the simulator
throws an error. Fortunately the solution is simple. You can either create
a subtype BitPosType to be your integer 0 to 10 and then convert your
BitPos + 1 (which is just an integer not BitPosType) as follows:

architecture ARCH of RX_UNIT is
subtype BitPosType is integer range 0 to 10;
signal BitPos: BitPosType;
begin

SAMPLING : process(CLK)
begin
if Rising_Edge(CLK) then
BitPos <= BitPosType'(BitPos + 1); -- increase by default with
type conversion
if BitPos >= 10 then -- stop bit
BitPos <= 0;
DONE <= '1'; -- signal available data
else
DATA(BitPos) <= Rx; -- store data bit
end if;
end if;
end process;

end ARCH;

or move the increment of BitPos inside the second if clause as follows:

architecture ARCH of RX_UNIT is
signal BitPos: integer range 0 to 10;
begin

SAMPLING : process(CLK)
begin
if Rising_Edge(CLK) then
if BitPos >= 10 then -- stop bit
BitPos <= 0; -- reset counter to 0
DONE <= '1'; -- signal available data
else
BitPos <= BitPos + 1; -- otherwise increment
DATA(BitPos) <= Rx; -- store data bit
end if;
end if;
end process;

end ARCH;

I hope this is what you are after.

Cheers,

Pete.
 
V

Valentin Tihomirov

The simulator will enforce your limits.
You can answer this question yourself just by running
a simulation and looking at the waveform values.

You might find that:

if BitPos = 10 then -- stop bit

is comparing the value that existed at
the previous clock so that the you end
up off by one on your limit.

Try it and see.

-- Mike Treseler

May be "stop bit" expression is misleadind, simulator stops in different
place.

if SampleCnt = 7 then
BitPos <= BitPos + 1; -- ModelSim stops here
if BitPos = 10 then -- STOP condition (UART stop bit)
BitPos <= 0;
.. -- check stop bit is '1'


I'm writing here just because when Sample = 7 and BitPos = 10 ModelSim shows
me message "Value 11 is out of range 0 to 10" and does not proceed. I
understand which signals I have at which cycles. There is no condition where
BitPos = 11; my logic prevents this. Please, tell me where is my (0..10)
constraint violated? I expect simulator to warn me only when things go wrong
due to inconsistency or a hole in my logic. I don't not want it to stall
when everithing is going as planed.

May be the problem is in a ref. point, a tradition or a definition but not
in my logic? Logically, I could not understand why does millenium start at
year 2001 until I was informed that the first century started in year 001.
 
P

Peter Molesworth

I do worry because ModelSim does. It abandons simulation alerting that 11
cannot be assigned to BitPos. This also means that no aoutomatic rollback
from 10 to 0 is generated. Therefore, these your words are not true and
making the wrap explicit makes sense.

See my other post aswell but basically:

BitPos is integer (restricted in range but still integer) therefore the
result of BitPos + 1 is also an integer which is not constrained by the
range of BitPos so the calculated next value for BitPos when the current
value is 10 is 11 not 0. I know that you have overridden this further down
with the assignment BitPos <= 0 but at the point the increment is
calculated there is an error.

Cheers,

Pete.
 
V

Valentin Tihomirov

value is 10 is 11 not 0. I know that you have overridden this further down
with the assignment BitPos <= 0 but at the point the increment is
calculated there is an error.

YES! SUCCESS! I caught Model Sim out!!!

As we all know from basic courses and simulation tutorials, assertion in
VHDL takes place when all branches has been analyzed and process is frozen.
ModelSim does not know such a basic rule! Should I report this behaviour to
support?
 
P

Peter Molesworth

YES! SUCCESS! I caught Model Sim out!!!

As we all know from basic courses and simulation tutorials, assertion in
VHDL takes place when all branches has been analyzed and process is
frozen.
ModelSim does not know such a basic rule! Should I report this behaviour
to
support?

I'm glad I was finally able to help :) I would probably run this one past
modeltech support if I were you just to see what they have to say for
themselves. The only thing that I can think of in their defense is that
they are calculating the value ready to be assigned after the next clock
edge. In their internal data structure this will probably be of the same
type as BitPos and therefore you are assigning an out of range value to
this data structure. However I reckon it's still a bug!

Cheers,

Pete.
 
M

Mike Treseler

Valentin said:
I'm writing here just because when Sample = 7 and BitPos = 10 ModelSim shows
me message "Value 11 is out of range 0 to 10" and does not proceed. I

What happens to your simulation if you use 9 instead of 10?

if BitPos = 9 then -- stop bit

Does that get it lined up?

-- Mike Treseler

-- This thread is one case for the
-- clarity of unsigned variables over
-- integer signals when doing math.
 
V

Valentin Tihomirov

What happens to your simulation if you use 9 instead of 10?

if BitPos = 9 then -- stop bit

When BitPos = 9 it increments to 10 as proceeded. At the next cycle
simulator fails to calculate next value of 0. Where do you see comparison to
9? It doesn't matter. Peter has got myproblem, see last posts. May be you
have to add something.
 
V

Valentin Tihomirov

Despite LRM stands for my logic ...


"internal data structure this will probably be of the same type as BitPos
".

This internal data structure is a model of combinational logic calculating
next state of register. Which type will it have? Only synthesier/optimizer
knows the answer. Simulator just should predict HW as precisely as possible.
Will both synthesis and simulation agree that 4-bit is enaught if BitPos
range 0 to15? What about different encoding schemes? That is why, I've
called this issue a corner case waiting VHDL community to explain me
details. I start wondering why the issue is not well understood.
 
E

Edwin Naroska

Hi,

Peter said:
I'm glad I was finally able to help :) I would probably run this one
past modeltech support if I were you just to see what they have to say
for themselves. The only thing that I can think of in their defense is
that they are calculating the value ready to be assigned after the next
clock edge. In their internal data structure this will probably be of
the same type as BitPos and therefore you are assigning an out of range
value to this data structure. However I reckon it's still a bug!

IMHO, it is bug. The following is cited from Section
8.4.1 "Updating a projected output waveform" of the LRM:

"...
No subtype check is performed on the value component of a
new transaction when it is added to a driver. Instead, a
subtype check that the value component of a transaction
belongs to the subtype of the signal driven by the driver
is made when the driver takes on that value. See 12.6.1."

It look like ModelSim is doing range checking when the
new transaction is *added* to the driver. I guess the major
reason for this is to improve simulation speed.
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top