I feel confused by "else null" statement:
if rst = '1' then
count <= 0;
elsif clk'event and clk = '1' then
if(INPUTEND = '1') then
...
end if;
end if;
I learned from books that I should exhaust all branches of "if"
statement, so I write in the following way:
if rst = '1' then
count <= 0;
elsif clk'event and clk = '1' then
if (INPUTEND = '1') then
...
else
null;
end if;
else
null;
end if;
But I also saw on the Internet sometimes people don't write code in my
cubersome way...
Can anybody clarify a little for me? When I need to write this "else
null", and when I don't need it?
Thanks a lot,
-Walala
"walala" <miz...@yahoo.com> wrote in message
news:6f348bd1.03091...@posting.google.com...
Thank you for your answer...
But it is unclear that which style is better...Can you tell me? (A) or (B)?
By the way, I really don't have anything to do in "else" block, so I put
"null"... will that still infer a latch?
< < "u had better put something in the else{}, otherwise you get a latch..."
(A)
> > if rst = '1' then
> > count <= 0;
> > elsif clk'event and clk = '1' then
> > if(INPUTEND = '1') then
> > ...
> > end if;
> > end if;
> >
(B)
*Registers:*
In the above example the if-statement is in a *clock-section*.
For example:
if(INPUTEND = '1') then
output <= inputsignal1;
end if;
The synthesisis-tool generates a register for the signal called output.
The clock input of the register is connected to the clock, and the
enable signal of the register is generated by a block of logic. Here it
is obviously, that there don't needs to be logic.
Attention: It doesn't matter if here is a else-branch. In any case a
register will be generated.
*Latches:*
Latches are elements, that are triggered by a signal.
If you write the following out of a clock section then the
synthesis-tool generates logic.
if(INPUTEND = '1') then
output <= inputsignal;
else
output <= inputsignal;
end if;
But if you write only:
if(INPUTEND = '1') then
output <= inputsignal;
end if;
the synthesis tool has to generate a latch because it can't generate
logic because it can't generate a boolean equation for the logic. So it
has to generate a latch.
Some architectures don't have latches, so they shouldn't used.
*Avoidance of Latches:*
To avoid (unwanted) latches you either have to desribe what will happen
with each signal in each branch (like in the logic-example) or do the
following.
If you are only interested what happens if INPUTEND='1' and the other
cases don't care, you can set a default value for the signal output.
Then in all cases where you haven't specified, what should be happen
with the ouput-signal the standard value is used by the synthesis-tool
and logic is genereated. So you can save code and avoid the generation
of latches.
A little example (out of a clock section again):
output <= (others=>'0');
if(INPUTEND = '1') then
output <= inputsignal;
end if;
It gets only the value of inputsignal, when INPUTEND='1', in all other
not explicit specified cases it gets the value zero.
I hope this helps you understand the problem.
I can't say anything about the sense of null-statements in the
else-branches, because I never used it there.
Regards,
Ingmar Seifert
if rst = '1' then
count <= 0;
elsif clk'event and clk = '1' then
if (INPUTEND = '1') then
...
A <= B+C;
else
-- null;
A <= A;
end if;
-- else
-- null;
end if;
"walala" <miz...@yahoo.com> wrote in message
news:bju4q1$afq$1...@mozo.cc.purdue.edu...
Thank you very much for your complete and informative explanation for
such a newbie as me. I recommend this article to be assembled into
VHDL FAQ... :=)
I now understand that in a clocked section, the "else" branch can be
safely ignored since it will be a register anyway... I also understand
that special care should be taken when the "if" statement is outside
the clocked section...
I want to further ask:
p0: PROCESS(rst, clk)
BEGIN
if rst = '1' then
for I in 0 to 7 loop
for J in 0 to 7 loop
XX(I)(J)<=0;
end loop;
end loop;
elsif (clk'event and clk = '1') then
XX(POSY)(POSX)<=CONV_INTEGER(X);
else
...
end if;
END PROCESS p0;
I the above code, since the "else" part is outside the clocked
section, but parallel to the asynchonous reset section, do I need to
put something inside the "else" branch? Or, can I safely ignore the
"else" branch?
I hope you can further clarify this issue for me!
Thank you very much,
-Walala
Ingmar Seifert <ingmar....@s1998.tu-chemnitz.de> wrote in message news:<bjut2p$r1o$1...@anderson.hrz.tu-chemnitz.de>...
Thanks ;-).
It took me some time too to understand when and why a latch is
synthesized, why a register is put in and all these things. In online
ressources (as well as in many books) you often find the standard syntax
desription. Often examples (and often very easy ones) are given without
a connection to the synthesis result. Unless I write a testbench, this
is very important to me. I don't write the code just for fun.
But a lot of authors don't bother, so it's hard to get some answers to
important questions.
>
> I now understand that in a clocked section, the "else" branch can be
> safely ignored since it will be a register anyway... I also understand
> that special care should be taken when the "if" statement is outside
> the clocked section...
>
> I want to further ask:
>
> p0: PROCESS(rst, clk)
> BEGIN
> if rst = '1' then
> for I in 0 to 7 loop
> for J in 0 to 7 loop
> XX(I)(J)<=0;
> end loop;
> end loop;
> elsif (clk'event and clk = '1') then
> XX(POSY)(POSX)<=CONV_INTEGER(X);
> else
> ...
> end if;
> END PROCESS p0;
>
>
> I the above code, since the "else" part is outside the clocked
> section, but parallel to the asynchonous reset section, do I need to
> put something inside the "else" branch? Or, can I safely ignore the
> "else" branch?
I'm sure you have this from a book. No, you don't need to put something
in it. As you said, it is not clocked.
if rst = '1' then
for I in 0 to 7 loop
for J in 0 to 7 loop
XX(I)(J)<=0;
end loop;
end loop;
This means only, that the rst signal is connected to the registers that
form your matrix.
If you would put something in the else branch I think logic would be
generated. But I'm not 100 percent sure about this.
Could anyone confirm this?
> -Walala
>
Could you please use your real name for further posts.
In usenet it's common to post with real name. Some people ignore threads
without real names and so you get fewer answers.
Regards,
Ingmar Seifert
>
> I learned from books that I should exhaust all branches of "if"
> statement, so I write in the following way:
>
> if rst = '1' then
> count <= 0;
> elsif clk'event and clk = '1' then
> if (INPUTEND = '1') then
> ...
> else
> null;
> end if;
> else
> null;
> end if;
>
>
> But I also saw on the Internet sometimes people don't write code in my
> cubersome way...
First time I've seen it.
>
> Can anybody clarify a little for me? When I need to write this "else
> null", and when I don't need it?
It's just style.
It will compile the same either way.
Consider leaving out the
else clause if you're not using it.
-- Mike Treseler
It does imply "else count <= count ;". Note, don't do this
as it causes simulations to run slower (it schedules signal count
to get the value from the expression count).
For your loop code,
p0: PROCESS(rst, clk)
BEGIN
if rst = '1' then
for I in 0 to 7 loop
for J in 0 to 7 loop
XX(I)(J)<=0;
end loop;
end loop;
elsif (clk'event and clk = '1') then
...
You can replace the loop with:
if rst = '1' then
XX <= (others => (others => 0) ) ;
Cheers,
Jim Lewis
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:J...@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787
Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Good code! Thank you very much for pointing out that me for me! I did not
know I can do in such a simpler way before... Let me have a try any rate!
-Walala
> p0: PROCESS(rst, clk)
> BEGIN
> if rst = '1' then
> for I in 0 to 7 loop
> for J in 0 to 7 loop
> XX(I)(J)<=0;
> end loop;
> end loop;
> elsif (clk'event and clk = '1') then
> XX(POSY)(POSX)<=CONV_INTEGER(X);
> else
> ...
> end if;
> END PROCESS p0;
Synth tools generally dislike "else" statements after "if" statements that
get implemented as an edge triggered flip-flop. The "elsif" after the
initial "if" is ok because this converts to a reset input on the
flip-flop.
Try to imagine the strange sort of logic that the else can lead to. The
XX value can be changed at any time the clk signal isn't rising. Doing
that in real life isn't easy.
--
--
kens...@rahul.net forging knowledge
> I have a small problem here, I have a sample code where I
> have a function specification which takes in a std_logic_vector, I have
> not specified the range, and when I make a call I pass a literal like
> 110101, now this becomes a special case where niether the formal nor the
> actual can be used to decide the range of the std_logic_vector (whether
> ascending or descending). Could someone guide me as to what should be
> the expected behaviour in such a case, does the LRM states something for
> such cases? Are by default literals like 110011 treated as ascending
> range std_logic_vectors ?
Here is the sample code:
use ieee.std_logic_arith.all;
entity Adder is
end Adder;
architecture rtl of Adder is
FUNCTION trim( vector : std_logic_vector; bits : INTEGER )
RETURN std_logic_vector IS
VARIABLE return_value : std_logic_vector(0 TO bits-1);
BEGIN
return_value := vector(bits-1 downto 0);
RETURN return_value;
END trim;
begin
B1 : block
signal t1 : std_logic_vector(5 downto 0);
signal ps2,ps3: std_logic_vector(4 downto 0);
Begin
t1 <= "111010";
ps2 <= trim("111010",5);
ps3 <= trim(t1,5);
end block B1;
end rtl;
------------------------------------------------------------------------
The problem is in the subprogram call statement
ps2 <= trim("111010", 5) , because in this particular case my function
trim treats it as an ascending range vector and gives an error because of
slicing in the reverse order at the statement
return_value := vector(bits-1 downto 0);
Is this the expected behavior? Are literals like "11011" treated as
ascending range vectors by default?
It would be great if someone can give me some clues on this.
Thanks,
Nitin.
To be sure that a function is 'range' independent you can align it. In your
function this could have the following form (see --**).
FUNCTION trim( vector : std_logic_vector; bits : INTEGER )
RETURN std_logic_vector IS
constant vector_i : std_logic_vector(vector'LENGTH-1 DOWNTO
):=vector; --****
VARIABLE return_value : std_logic_vector(0 TO bits-1);
BEGIN
return_value := vector_i(bits-1 downto 0);
RETURN return_value;
END trim;
From the past I know that there was a synthesis tool that did not support
this constant declaration.
A work around is then to declare a variable and assign vector to it; i.e.
FUNCTION trim( vector : std_logic_vector; bits : INTEGER )
RETURN std_logic_vector IS
variable vector_i : std_logic_vector(vector'LENGTH-1 DOWNTO 0); --****
VARIABLE return_value : std_logic_vector(0 TO bits-1);
BEGIN
vector_i := vector; --**
return_value := vector_i(bits-1 downto 0);
RETURN return_value;
END trim;
Egbert Molenkamp
"Nitin Khurana" <nkhu...@cadence.com> wrote in message
news:404E9D24...@cadence.com...
FUNCTION trim( vector : std_logic_vector; bits : INTEGER )
RETURN std_logic_vector IS
alias a_vector : std_logic_vector(vector'LENGTH-1 DOWNTO 0) is
ector; --****
VARIABLE return_value : std_logic_vector(0 TO bits-1);
BEGIN
return_value := a_vector(bits-1 downto 0);
RETURN return_value;
END trim;
regards
fe
"Egbert Molenkamp" <remove_fun...@cs.utwente.nl> wrote in message
news:c2mhb9$s0p$1...@ares.cs.utwente.nl...
> The type std_logic_vector is declared is an array with natural indices.
> Therefore if no range is specified the range will be from 0 to
> vector'LENGTH-1 (ascending).
> In case of type string (with positive indices) it is from 1 to
> vector'LENGTH.
>
> To be sure that a function is 'range' independent you can align it. In
your
> function this could have the following form (see --**).
>
> FUNCTION trim( vector : std_logic_vector; bits : INTEGER )
> RETURN std_logic_vector IS
> constant vector_i : std_logic_vector(vector'LENGTH-1 DOWNTO
> ):=vector; --****
> VARIABLE return_value : std_logic_vector(0 TO bits-1);
> BEGIN
> return_value := vector_i(bits-1 downto 0);
> RETURN return_value;
> END trim;
>
> From the past I know that there was a synthesis tool that did not support
> this constant declaration.
> A work around is then to declare a variable and assign vector to it; i.e.
>
> FUNCTION trim( vector : std_logic_vector; bits : INTEGER )
> RETURN std_logic_vector IS
> variable vector_i : std_logic_vector(vector'LENGTH-1 DOWNTO
Is there any LRM Section which explicitly states that if there is no range
specified the range would be 0 to vector'LENGTH-1 (ascending)?
Would really appreciate if you can guide me on this.
Thanks,
Nitin.
Let me elaborate a little bit.
Type std_logic_vector is declared as:
type std_logic_vector is array (natural range <>) of std_logic.
The index subtype is natural:
subtype natural is integer range 0 to integer'high.
Since this subtype is ascending the range in your example in ascensing.
I added an example in which type my_int is descending.
The left most index is in this case integer'high.
entity which_index is
end which_index;
architecture demo of which_index is
type my_int is range integer'high downto integer'low;
type ar is array (my_int range <>) of bit;
constant car : ar := "101";
begin
assert false report my_int'image(car'left) severity note;
end demo;
# ** Note: 2147483647
# Time: 0 ns Iteration: 0 Instance: /which_index
Egbert Molenkamp
"Nitin Khurana" <nkhu...@cadence.com> wrote in message
news:404FF2D4...@cadence.com...