1
\$\begingroup\$

I'm trying to learn VHDL and I came across some example code for a counter that I find somewhat strange.

I understand what it does but I'm not sure why it is written the way it is.

The code is the following:

entity counter is

generic(n: natural :=2);
port(   clock:  in std_logic;
    clear:  in std_logic;
    count:  in std_logic;
    Q:  out std_logic_vector(n-1 downto 0)
);
end counter;

architecture behv of counter is           

    signal Pre_Q: std_logic_vector(n-1 downto 0);

begin

    -- behavior describe the counter

    process(clock, count, clear)
    begin
    if clear = '1' then
        Pre_Q <= Pre_Q - Pre_Q;
    elsif (clock='1' and clock'event) then
        if count = '1' then
        Pre_Q <= Pre_Q + 1;
        end if;
    end if;
    end process;    

    -- concurrent assignment statement
    Q <= Pre_Q;

end behv;

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

Can't we just replace this line

Pre_Q <= Pre_Q - Pre_Q;

with something like this? (I'm not sure if I can do this)

Pre_Q <= 0;

Is there any reason why I should use the first method instead of the second?

I apologize for deleting my previous question but I made a mistake when rewriting the code and I forgot to explain what my doubt really was.

\$\endgroup\$
  • \$\begingroup\$ It would be a good idea to post the entire code and just one process from it, we know about your signals so answering the question is not possible. \$\endgroup\$ – user34920 Oct 29 '14 at 12:11
  • \$\begingroup\$ @user34920 I just included the complete code. \$\endgroup\$ – Bruno Ferreira Oct 29 '14 at 12:18
1
\$\begingroup\$

The only advantage to writing it the first way that I can see is that, I suppose, it's type-independent. Maybe the original coder wanted to be able to copy and paste the code without modifying it (though one would think the signal name would need to be modified anyway), and depend on the synthesis tool to optimize it (or not). Personally, I do not think this is a good justification - it's less clear, and copying/pasting code without looking at it carefully is never a good idea.

Your assignment statement will change depending on your type. Pre_Q <= 0; for integer types, Pre_Q <= (others => '0'); (or equivalent) for vector types, etc.

(I see you've updated the question, and given that you're using a std_logic_vector, you'd want the latter)

response to comment

You wrote:

I do not understand the assignment for vectors. Can't I just use Pre_Q <= '0'?

A std_logic_vector is an array of std_logic, each one of which is an enumeration of 9 possible values/states (including '0' and '1'). They're not technically 0s and 1s to the language, odd though that may seem. So a std_logic_vector is not inherently a numeric type, and can only be treated as such with function overloads. If you try to assign '0' to Pre_Q, you are attempting to assign a scalar (in this case, technically a character literal) to a vector, and these types are not compatible in this way. Nor can you assign the integer literal 0 - while it may be obvious to almost anyone what you are intending to do, VHDL's strong typing does not allow this.

When you use (others => '0'), you are using an array aggregate. others is a keyword that refers to all indices of the array that have not been explicitly assigned in the aggregate (in this case, all of them), and so when you map the "other bits" to '0', you're zeroing the entire vector. (You can also use a conversion function, but (others => '0') is the more conventional idiom)

\$\endgroup\$
  • \$\begingroup\$ That makes sense. I do not understand the assignment for vectors. Can't I just use Pre_Q <= '0';? \$\endgroup\$ – Bruno Ferreira Oct 29 '14 at 12:24
  • \$\begingroup\$ See updated answer. \$\endgroup\$ – fru1tbat Oct 29 '14 at 12:59
  • \$\begingroup\$ Ok, now I understand, and it seems that I have a long way until I learn VHLD. Thank you very much for your explanation. \$\endgroup\$ – Bruno Ferreira Oct 29 '14 at 13:05
  • 2
    \$\begingroup\$ More plausible that the original writer didn't really know VHDL, and Pre_Q - Pre_Q was the first alternative to 0 that he could get to compile. I have seen some strangely warped code written that way... \$\endgroup\$ – Brian Drummond Oct 29 '14 at 15:13
  • \$\begingroup\$ True, that is a bit more likely... \$\endgroup\$ – fru1tbat Oct 29 '14 at 15:20
0
\$\begingroup\$

Good question. My intuitive answer would be that there is no difference, and that you should write Pre_Q <= 0; because it expresses the intent more clearly. But that is just my opinion, without any tests or investigation.

Two answers that are good irrespective of my opinion:

  1. Ask the guy who wrote this. And suggest that they add more documentation so that people would understand his code.

  2. Run both version through a synthesis tool to see if there is any difference. (Again, my best guess is that there won't be any.)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.