# VHDL 8bit counter help

Status
Not open for further replies.

#### superdave14

##### Newbie level 3
Hello guys/gals first post.

In a grad class, advanced digital logic and the instructor is learning with the students so thus far its been interesting. Needless to say a lot of self teaching. Anyways we are trying to build a 8 bit counter to count up to 99 then reset to send out to the 7 seg's and i am having issues with the code. I can get the lower 4 bits to count and reset to 0 after it reaches 8 with a 3.5 nanosecond propagation delay on the 10. The issue is when i try to increment the high nibble on the reset of the lower nibble it goes high for 10 nano but then resets back to zero and i have no idea why. Can someone help me with the code? Again im a complete noob and some of the code i figured out for myself through just trying stuff. Thanks

Guess it would help to note im using Quartus II version 9.1 SP2

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter is
port(C, CLR : in std_logic;
Q : out std_logic_vector(7 downto 0));
end counter;
architecture archi of counter is
signal tmp: std_logic_vector(7 downto 0);
begin
process (C, CLR)
begin
if (CLR='1') then
tmp <= "00000000";
elsif (C'event and C='1') then
tmp <= tmp + 1;
end if;
-- to split up the 8 bit bus use your bus name + the bus length such as
--tmp(3 downto 0) is the lower half of the 8 bits. This is how you islate the bus in
--in VHDL code. Figured it out all by myself.
if (tmp(3 downto 0) = "1001") then
tmp(3 downto 0) <= "0000";
tmp(7 downto 4) <= + "0001";
end if;

end process;
Q <= tmp;
end archi;

Last edited:

#### permute

i'm not really a fan of that coding style.

basically, you should look at vendor examples. Eg, xilinx and altera. This is where you'll find the best info. They have application engineers that see common issues in customer designs as well as work with the software engineers to get the tools to work better. They will typically give you much better advice than the people who are self-taught, or have migrated from another related field.

In you case:
Just use Clk. its really a popular name.

people are trying to move away from std_logic_unsigned to numeric std. This might be annoying for you though, as numeric_std is more academic than practical. VHDL2008's new features might actually make it a bit better, but that's more of an advanced topic. It might be ok to get it working with SLU first, then look into the handholding required for numeric_std.

Try to keep your code inside the if clk'event and clk = '1' statement. I'm not sure exactly what the code you've written will do. For example, the CLR signal isn't clearly defined. If Clr occurs while tmp(3 downto 0) = 9, then the sim should latch the lower case -- tmp = 10, until a clock event happens. the synthesizer might give warnings and just assume tmp is in the sensitivity list, which would reset the count to 0 (tmp -> 10, process evaluated a second time, tmp -> 0).

I'm not sure the tmp <= + 1 is portable. It might be a VHDL2008 feature. this could be important if you ever want to use the code elsewhere.

You probably should break tmp up into two 4b counters. use an if-else statement inside the clocked statement.

#### hareshcooleng

##### Member level 1
I think you use the book of VHDL auther is bhasker. it is nice book you read for the counter.

---------- Post added at 05:36 ---------- Previous post was at 05:26 ----------

you have license version for quartus pls rply fast.

#### superdave14

##### Newbie level 3
I agree i should break up the 8bit bus, but the instructor wanted to see if it could be done without doing that, and frankly at this point so do it. I pretty much have it broken, I am just not sure how to increment the second nibble which is where the problem lies. Thanks for the input.

#### permute

sure, you _can_ do it. Even algorithmically:
Code:
for (ii in cnt'length/4-1 downto 1) loop
if (cnt(4*(ii)-1 downto 4*(ii-1))="1001") then -- "if the immediately lower nibble is 9"
if(cnt(4*(ii+1)-1 downto 4*(ii))="1001") then -- "if this nibble is 9"
cnt(4*(ii+1)-1 downto 4*ii) <= "0000"; -- "advance to 0"
else
cnt(4*(ii+1)-1 downto 4*ii) <= cnt(4*(ii+1)-1 downto 4*ii) + 1; -- "increment this nibble"
end if;
end if;
end loop;
if cnt(3 downto 0) = "1001" then -- if the lsn = 9
cnt(3 downto 0) <= "0000"; -- advance to 0
else
cnt(3 downto 0) <=cnt(3 downto 0) + 1; -- increment
end if;

and there really are better ways than that. the above will work for a counter with 2+ decimal digits. (again, I assume that SLU is used, or cnt is signed/unsigned). SLV's are like VHDL's void* types -- you can make a long SLV and put other signals inside. This is seen mostly when coding standards don't allow for array or record types.

Last edited:

#### superdave14

##### Newbie level 3
Thanks permute, you did not have to go through the trouble of writing all that for me, i do appreciate it. I will try this out when i get off work tonight and see how it runs.

Thanks for the assistance and will probably be posting more after the next class. VHDL has really got me curious. Thanks.

D.K.

#### superdave14

##### Newbie level 3
Again new to VHDL..

is the ii suppose to be defined somewhere above or is it an understood variable in the for loop? I know in C++ you can define variables in for loops straight away if you do not want them global, so is this the case in this loop. I ask because i am getting a II not defined error.

Thanks.

sure, you _can_ do it. Even algorithmically:
Code:
for (ii in cnt'length/4-1 downto 1) loop
if (cnt(4*(ii)-1 downto 4*(ii-1))="1001") then -- "if the immediately lower nibble is 9"
if(cnt(4*(ii+1)-1 downto 4*(ii))="1001") then -- "if this nibble is 9"
cnt(4*(ii+1)-1 downto 4*ii) <= "0000"; -- "advance to 0"
else
cnt(4*(ii+1)-1 downto 4*ii) <= cnt(4*(ii+1)-1 downto 4*ii) + 1; -- "increment this nibble"
end if;
end if;
end loop;
if cnt(3 downto 0) = "1001" then -- if the lsn = 9
cnt(3 downto 0) <= "0000"; -- advance to 0
else
cnt(3 downto 0) <=cnt(3 downto 0) + 1; -- increment
end if;

and there really are better ways than that. the above will work for a counter with 2+ decimal digits. (again, I assume that SLU is used, or cnt is signed/unsigned). SLV's are like VHDL's void* types -- you can make a long SLV and put other signals inside. This is seen mostly when coding standards don't allow for array or record types.

#### permute

hmm, actually it might be:
for ii in cnt'length/4-1 downto 1 loop

#### TrickyDicky

Again new to VHDL..

is the ii suppose to be defined somewhere above or is it an understood variable in the for loop? I know in C++ you can define variables in for loops straight away if you do not want them global, so is this the case in this loop. I ask because i am getting a II not defined error.

Thanks.

Remove the brackets from around the "ii in ... " bit. Its trying to eveluate the stuff inside the brackets on its own, which has no meaning. In VHDL, the for loop value (which is a constant) can only be declared in the for loop, not outside.

so "for i in 0 to 3 loop" creates a constant i that changes from loop to loop (it has to be a constant because it is locally static).

As you are learning now, It may be benificial to switch to numeric_std now. It may be a bit of a pain (like permute says) but it will teach you about VHDL's typing system. typing is one of VHDL's great strengths, and too many people ignore it by making everything a std_logic_vector. If when you start building state machines, or do fixed point maths, you'll really find it a benefit.

Back to the for loop, you can actually have the loop identifier as any type. So you can do stuff like this:

Code:
type shapes is (triangle, square, pentagon, hexagon, septagon, octagon);

for i in square to septagon loop --misses triangle and octagon
end loop;

in addition, you can create array types using this too. You can write the code in a way to almost be self documenting, without comments:

Code:
type n_sides_t is array(shapes range <>) of integer;

constant N_SIDES : n_sides_t(triangle to octagon) := (3,4,5,6,7,8);

......... then in code:

for i in N_SIDES(square) to N_SIDES(octagon) loop --looks up integers
end loop;

I know this is overly complicated, but shows the stuff you can do with VHDL (and is synthesisable).

Last edited:

Status
Not open for further replies.