A beginner's question

B

Blake

Guest
I'm trying to teach myself to work with CPLD's using some of the many good
tutorials on the web. My first project includes a counter that should
continuously count from 0 to 99, in step size that can be selected by
external jumpers.

It sounded easy enough to me, but . . . I normally don't like to ask for
help when I can dig into the books for myself, but this time I've run into
a dead end.

Using the code below, I can't cure a sintax error message - something to the
effect that the TO_UNSIGNED function must have the size specified. (I think
I did specify the size - I wish I had remembered to email myself the exact
message from work). Do any of you experienced programmers have suggestions
to get me straightened out on this one? If so, it would be a big help.

-----------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;


entity COUNTER is port (CLOCK: in std_logic;
STEP: in std_logic_vector (5 downto 0);
COUNT: out std_logic_vector (6 downto 0));
end COUNTER;

architecture Behavioral of COUNTER is

begin

constant STEPI: integer range 0 to 63 ;
variable COUNTI: integer range 0 to 127 := 0 ;

STEPI <= TO_INTEGER (TO_UNSIGNED(STEP));

STEP_COUNT: process
begin
loop
wait until CLOCK='1';
COUNTI := (COUNTI + STEPI) mod 100 ;
end loop ;
end process STEP_COUNT;

COUNT <= TO_STDLOGICVECTOR( TO_UNSIGNED ( COUNTI,7 ));

end Behavioral;
 
Blake wrote:
I'm trying to teach myself to work with CPLD's using some of the many good
tutorials on the web. My first project includes a counter that should
continuously count from 0 to 99, in step size that can be selected by
external jumpers.

It sounded easy enough to me, but . . . I normally don't like to ask for
help when I can dig into the books for myself, but this time I've run into
a dead end.

Using the code below, I can't cure a sintax error message - something to the
effect that the TO_UNSIGNED function must have the size specified. (I think
I did specify the size - I wish I had remembered to email myself the exact
message from work). Do any of you experienced programmers have suggestions
to get me straightened out on this one? If so, it would be a big help.

-----------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

entity COUNTER is port (CLOCK: in std_logic;
STEP: in std_logic_vector (5 downto 0);
COUNT: out std_logic_vector (6 downto 0));
end COUNTER;

architecture Behavioral of COUNTER is

begin

constant STEPI: integer range 0 to 63 ;
variable COUNTI: integer range 0 to 127 := 0 ;

STEPI <= TO_INTEGER (TO_UNSIGNED(STEP));

STEP_COUNT: process
begin
loop
wait until CLOCK='1';
COUNTI := (COUNTI + STEPI) mod 100 ;
end loop ;
end process STEP_COUNT;

COUNT <= TO_STDLOGICVECTOR( TO_UNSIGNED ( COUNTI,7 ));

end Behavioral;
I don't see anything wrong with your use of "TO_UNSIGNED", except
possibly that you are including two incompatible libraries,
IEEE.STD_LOGIC_UNSIGNED and IEEE.NUMERIC_STD. Othewise the code looks
good. Well, maybe I don't understand why you are defining STEPI as a
constant and then separately using it on the left hand side of an
assignment statement. Is that legal? Oh yeah, I don't think you can
declare a variable (COUNTI) outside the process. And your wait
statement until "CLOCK='1'" does not look for the edge. So the loop
will run infinitely in zero time, IIRC.

But other than that it looks good... did I miss anything? :)

Don't feel bad. I found VHDL to be a bit hard to learn. It is very
different from software programming and there are a lot of subtleties.
Try looking at examples and figure out how and why their code is
different from yours.

--

Rick "rickman" Collins

rick.collins@XYarius.com
Ignore the reply address. To email me use the above address with the XY
removed.

Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design URL http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX
 
Blake wrote:
Using the code below, I can't cure a sintax error message - something to
the effect that the TO_UNSIGNED function must have the size specified. (I
think I did specify the size - I wish I had remembered to email myself the
exact message from work). Do any of you experienced programmers have
suggestions to get me straightened out on this one? If so, it would be a
big help.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
I think you don't need both numeric_std, and std_logic_arith/unsigned. Try
compiling with just numeric_std (and std_logic_1164 of course), and see how
that works. The error might be because of multiple definitions of the
to_unsigned function.

Regards,

Pieter Hulshoff
 
Blake,
Following up on your question and the response of Pieter and
rickman,

Rule of thumb:
Don't use both std_logic_arith and numeric_std in the same
design. For new designs, I recommend using numeric_std.

More detail than you need understand for now, but ...
Both of these packages define the types signed and unsigned.
As a result, if you reference both in the same entity,
the types are not directly referencable by their
simple name, signed and unsigned, but rather you have to
give a fully selected name: ieee.numeric_std.unsigned or
ieee.std_logic_arith.unsigned. YUCK.

Irony:
Contrary to what rickman said, not only can you use
std_logic_unsigned with numeric_std, there are less
issues doing this than with using std_logic_unsigned
with std_logic_arith (the package it was designed to
be used with).

Long term there with be a numeric_unsigned package
to use with numeric_std.


Going further with your code, your life would be alot
easier if you would stick with array types.
In fact, since you included the package std_logic_unsigned,
you can do all the unsigned math with std_logic_vector
without needing to do any type conversions.

Why don't you try rewriting the code using only
std_logic_vector. Also make COUNTI a variable
and don't initialize it, instead, use a reset
signal.

Regards,
Jim
P.S. If you are doing this for work and want to get up
to speed quickly, we have a beginners VHDL class comming up
in a couple of weeks in DC. See our schedule at:
http://www.synthworks.com/public_vhdl_courses.htm
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


constant STEPI: integer range 0 to 63 ;
variable COUNTI: integer range 0 to 127 := 0 ;

STEPI <= TO_INTEGER (TO_UNSIGNED(STEP));

STEP_COUNT: process
begin
loop
wait until CLOCK='1';
COUNTI := (COUNTI + STEPI) mod 100 ;
end loop ;
end process STEP_COUNT;

COUNT <= TO_STDLOGICVECTOR( TO_UNSIGNED ( COUNTI,7 ));

I'm trying to teach myself to work with CPLD's using some of the many good
tutorials on the web. My first project includes a counter that should
continuously count from 0 to 99, in step size that can be selected by
external jumpers.

It sounded easy enough to me, but . . . I normally don't like to ask for
help when I can dig into the books for myself, but this time I've run into
a dead end.

Using the code below, I can't cure a sintax error message - something to the
effect that the TO_UNSIGNED function must have the size specified. (I think
I did specify the size - I wish I had remembered to email myself the exact
message from work). Do any of you experienced programmers have suggestions
to get me straightened out on this one? If so, it would be a big help.

-----------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;


entity COUNTER is port (CLOCK: in std_logic;
STEP: in std_logic_vector (5 downto 0);
COUNT: out std_logic_vector (6 downto 0));
end COUNTER;

architecture Behavioral of COUNTER is

begin

constant STEPI: integer range 0 to 63 ;
variable COUNTI: integer range 0 to 127 := 0 ;

STEPI <= TO_INTEGER (TO_UNSIGNED(STEP));

STEP_COUNT: process
begin
loop
wait until CLOCK='1';
COUNTI := (COUNTI + STEPI) mod 100 ;
end loop ;
end process STEP_COUNT;

COUNT <= TO_STDLOGICVECTOR( TO_UNSIGNED ( COUNTI,7 ));

end Behavioral;
 
Rick,
I stand corrected. The other library I normally use is
ieee.std_logic_1164, not std_logic_arith. My mistake. :)
Next rev of VHDL will make this much more clear when the
IEEE package, numeric_unsigned is released. Once that
happens, it will be the preferred unsigned package.
Tool support should be quick as numeric_unsigned simply
calls the unsigned math functions from numeric-std.

Using std_logic_unsigned with numeric_std is not conventional,
however, for testbenches, I find it convenient to be able
to increment an address value which has the type
std_logic_vector. I use type ieee.numeric_std.unsigned for
all math applications (except sometimes, I use std_logic_vector
for counters).

The humor/irony I see is that not only do they work together,
they seem to work together than better than std_logic_unsigned
and std_logic_arith do.

Of course, heep in mind that what I have stated is what VHDL
allows. Some methodology police do not like usage of the
"unsigned" packages under even normal conditions.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Rick
Next rev of VHDL will make this much more clear when the
IEEE package, numeric_unsigned is released. Once that
happens, it will be the preferred unsigned package.
Tool support should be quick as numeric_unsigned simply
calls the unsigned math functions from numeric-std.


Doesn't numeric_std *have* an unsigned type?
Yes, called unsigned

Or does the numeric_unsigned package treat slv
as if it were unsigned?
Exactly.

And the package is std_logic_unsigned for now,
and numeric_unsigned with the next revision of
VHDL

Regards,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Many thanks to all of you for your help. I didn't get the chance to try your
suggestions today, but with new direction, I'm ready to retackle the
problem.

I feel foolish about declaring a variable outside the process; I had that
rule highlighted in my primer.

I'm a bit surprised to hear that the loop is unnecessary and that the
CLOCK=1 won't detect the clock edge; Those points came from sample code
published in a primer from the U. of Penn. The only change to their code
that I (intentionally) made was to add a variable step size and to convert
the output to a std_logic_vector. There must have been more going on than I
realized.

I know I still have a long way to go, but with your advice, I learned
something. Thanks again to all of you.

Blake
 

Welcome to EDABoard.com

Sponsor

Back
Top