- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I'm new to this forum, and very new to FPGAs. I've got myself a simple Cyclone II dev board and a copy of Quartus, and I'm attempting to learn some VHDL. I've just got to the stage of blinking my first LED... I have a very simple (I think) opening question regarding VHDL. I wanted to design a modulo-n frequency divider with a 32bit counter, and so I defined the type that I would later use for my counter as follows: type uint32 is range 0 to 16#ff_ff_ff_ff# ; (I also later tried subtype uint32 is integer range 0 to 16#ff_ff_ff_ff# ;) In both these cases 16#FF_FF_FF_FF# appears to have been interpreted as a signed two's complement integer, that is, as the value -1. My type therefore has the range 0 to -1, not 0 to 4294967296 as I intended. My question is, then, how would I define an unsigned integer as I intended? Thanks in advance. No doubt I'll be back with more daft questions very soon! (PS. What, if anything, is the difference between the types defined by the two lines of code above?)Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The basic answer is - you cant.
VHDL leaves integer to be platform defined - so it can be 16, 32 64 or however many bits the compiler choses to use - but most use 32 bit. And it is always signed. So FF_FF_FF_FF = -1. You cannot have a 32 bit unsigned integer in VHDL. Instead of trying to use integer for your uint32, why not use the unsigned type? this has an unlimited bit width, and you can define each signal as it's own width: signal a : unsigned(3 downto 0); signal b : unsigned(31 downto 0); signal c : unsigned(1023 downto 0); you can even define a subtype if you wanted: subtype uint32 is unsigned(31 downto 0);- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- (PS. What, if anything, is the difference between the types defined by the two lines of code above?) --- Quote End --- One is a type - and one is a subtype. subtypes are restricted versions of another type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Tricky,
That's really helpful, thanks. I'd understood that the width of the "built-in" integer was architecture dependent, it just hadn't clicked that it was always a signed type. Now I think of it, of course that's completely equivalent to C (which I'm more familiar with) where int a ; is a signed type (of architecture-dependent width) and unsigned int a ; is the unsigned of the same width. My textbook ("The students' guide to...") hasn't mentioned the "unsigned" type yet - the only integer type that's listed is called "integer". As I said, I'm very new to all this. I notice that your definition syntax is different to that used in the book, too. The form unsigned(3 downto 0) looks like a type conversion - it it related? Regarding my two example definitions: type uint32 is range 0 to 10 ; subtype uint32 is integer range 0 to 10 ; Do these produce two types which are functionally equivalent (with the same range and operators) but which are incompatible due to being different types? Thanks for the help!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the unsigned type is similar to the std_logic_vector type, in that it is an array of the std_logic type, but it is treated as an unsigned integer (there is also the signed type). Although it is very distinct from integer, as you cannot access individual bits from the integer type.
The type and subtype declarattions are functionally equivolent, because the subtype IS an integer type. It's not a type itself, it's a subtype.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah, yes. It's falling into place a little now. I've done a little googling off the back of your last post...
So "unsigned", "signed" and friends are not built-in, but provided by package ieee.numeric_std. That probably explain why the textbook doesn't list them as standard types. And the definition subtype uint32 is unsigned(31 downto 0); is an array definition, 32 bits of std_logic wide (not a number between 0 and 31!). And, if I have it right, the "signed", "unsigned" etc numeric types can be used as numbers because they overload the numerical operators like "+", "-", "=" etc. The plain "std_logic_vector" is not a number because it only defines logical operators. This makes a little more sense - it seems natural that in a "hardware definition language" one would be very interested in defining the range of a value in terms of its number of bits and specifying how they should be interpreted (signed, unsigned etc), and that individual bits should be easily accessible.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
anything in the ieee library (apart from std_logic_arith and std_logic_(un)signed) are part of the VHDL language specification, so you could term as "built in". It is just they need to be included when you write code. Integer and bit types are defined the in package std.standard which is included in every VHDL file by default.
Just to ensure you get the terminology correct, unsigned/signed dont overload any arithmetic operators, because they do no exist for any type. The "+", "-" etc are defined in the numeric_std library. Function overloading happens when you define a function with either different inputs or a more locally scoped version of the function - eg. you define a "+" function yourself that overloads the one you included from numeric_std (I would highly recommend you DONT do this). You are correct about std_logic_vector - it is meant to represent a bus of bits. Keep this style in you head. There will be many many examples out there that use the std_logic_(un)signed libraries that treat std_logic_vector as the type included by the library, because these libraries were created by synopsys before the '93 revision of VHDL that included numeric_std. They became adopted by all of the vendors (and some had different implementation to others!) and were compiled into the IEEE library, which makes people think they are part of the VHDL spec. They are safe to use now, but bare in mind that they are not part of the VHDL standard - you should be using numeric_std instead.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Just to ensure you get the terminology correct, unsigned/signed dont overload any arithmetic operators, because they do no exist for any type. The "+", "-" etc are defined in the numeric_std library. --- Quote End --- Thanks for the clarification - not overloaded, because there was no function defined in the first place. My question is answered, anyway... I'm sure there will be more where that came from though!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page