Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL Design Problem Issues

Status
Not open for further replies.

dzafar

Member level 4
Joined
Jan 17, 2017
Messages
76
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Activity points
690
Hello there,

I came across the following design problem

Untitled.png

Below is my approach towards the solution (which is incorrect). I do not understand why? I have some specific questions that I added as comments in the image below. And if the answers to my commented questions are 'yes/correct', then please explain why is the approach incorrect?

Untitled.png

Thanks in advance :)
 

First of all, these answers ignore the syntax errors in the code:

Questions first:
1. Incorrect.
2. No
3. yes, but why bother with type conversion at all?

This example shows that you assume VHDL is a programming language, like C. It is not. It is a hardware description language.
Did you draw the expected circuit before you wrote the code?
Without understanding what the circuit should be, you will write bad code.

Here, what happens on every edge of the clock is that CNT_temp is set to 100, and hence so is CNT. So you have a circuit that sets CNT to 0 at reset and 100 during run time.
 

Thanks TrickyDicky! Your answers are always well explained. Yeah, I did guess that at the end CNT_temp will just be 100 (to ge honest, I thought it would be 99).

When you say, "Did you draw the expected circuit before you wrote the code?", what do you mean?!

Also, I am totally a rookie at designing problems but really wanna learn. It would be great if you can provide some kind of 'recipie' that one can follow to approach such problems!

Also, does that mean CNT <= 0000 0000 is correct?!

Thanks much!
 
Last edited:

Here, what happens on every edge of the clock is that CNT_temp is set to 100, and hence so is CNT. So you have a circuit that sets CNT to 0 at reset and 100 during run time.
I expect a different behavior. CNT_temp isn't reset (except for a power on initialization), thus it should be increased by 100 every clock cycle until overflowing the default 32 bit number range.

In any case, a for loop doesn't implement the intended counter function.
 

I expect a different behavior. CNT_temp isn't reset (except for a power on initialization), thus it should be increased by 100 every clock cycle until overflowing the default 32 bit number range.

In any case, a for loop doesn't implement the intended counter function.

CNT_temp := i + 1;

i is the for-loop variable, and CNT_temp is never assigned from itself. hence why it will always be 100, as the last iteration gives:

CNT_temp := 99 + 1;

- - - Updated - - -

When you say, "Did you draw the expected circuit before you wrote the code?", what do you mean?!

I mean, did you take a pencil/pen and a piece of paper, and draw the circuit you're trying to implement? ie. gates an registers etc? Without understanding the circuit, your code will be like software, which will give bad results.

Also, does that mean CNT <= 0000 0000 is correct?!

I think you mean:

CNT <= x"00";

or

CNT <= "0000_0000";

This assumes you want CNT reset to 0, and not some other value.
 

You're of course right. I somehow thought of CNT_temp being incremented in the loop, but it isn't.
 

When you say, "Did you draw the expected circuit before you wrote the code?", what do you mean?!

Draw as in draw the logic circuit that does what you want.

e.g.

Capture.PNG
 

@dzfar,

A clocked process describes logic that can be accomplished within one clock cycle. This is why the for loop within the process doesn't really make sense.
 

Hi,
This is one way you could write the code for it.
I'm sorry for not including comments.
Code:
...
If clk’event and clk=’1’ then
     If HIGHER <= “1000” then
           If LOWER <= “1000” then
                  LOWER  <= LOWER + “0001”;
           Elsif LOWER = “1001” then
                  LOWER  <= “0000”;
                  HIGHER  <= HIGHER + “0001”;
           End if;
     Elsif HIGHER = “1001” then
           If LOWER <= “1000” then
                  LOWER  <= LOWER + “0001”;
           Elsif LOWER = “1001” then
                  LOWER  <= “0000”;
                  HIGHER  <= “0000”;
           End if;
     End if;
End if;
...
Hope it helps.
 

Hi,
This is one way you could write the code for it.
I'm sorry for not including comments.
Code:
...
If clk’event and clk=’1’ then
     If HIGHER <= “1000” then
           If LOWER <= “1000” then
                  LOWER  <= LOWER + “0001”;
           Elsif LOWER = “1001” then
                  LOWER  <= “0000”;
                  HIGHER  <= HIGHER + “0001”;
           End if;
     Elsif HIGHER = “1001” then
           If LOWER <= “1000” then
                  LOWER  <= LOWER + “0001”;
           Elsif LOWER = “1001” then
                  LOWER  <= “0000”;
                  HIGHER  <= “0000”;
           End if;
     End if;
End if;
...
Hope it helps.
It may be one way to write it, but it is not a good way to write it. LOWER should have nothing to do with the value of higher, it is a repeating count of 0-9 and doesn't need to even examine HIGHER.

Examine your code.
Code:
If clk’event and clk=’1’ then
     If HIGHER <= “1000” then
           [COLOR="#FF0000"]If LOWER <= “1000” then
                  LOWER  <= LOWER + “0001”;
           Elsif LOWER = “1001” then
                  LOWER  <= “0000”;[/COLOR]
                  HIGHER  <= HIGHER + “0001”;
           End if;
     Elsif HIGHER = “1001” then
[COLOR="#FF0000"]           If LOWER <= “1000” then
                  LOWER  <= LOWER + “0001”;
           Elsif LOWER = “1001” then
                  LOWER  <= “0000”;[/COLOR]
                  HIGHER  <= “0000”;
           End if;
     End if;
End if;
Notice the parts in red are identical.

- - - Updated - - -

Besides that what happens if LOWER or HIGHER ends up with 1010 through 1111 in it? It gets stuck forever. I prefer counting when less than the end value and clearing otherwise.
 

Hi ads-ee,
I had to omit some part of the code to make it less cumbersome.

I omitted the portion that deals with the undesired values so as to pass the counting process alone, which I think was the main point of the question.
It may be one way to write it, but it is not a good way to write it. LOWER should have nothing to do with the value of higher, it is a repeating count of 0-9 and doesn't need to even examine HIGHER
I examined HIGHER alongside LOWER here because I would only want to increment it if LOWER is 9 and HIGHER is less than 9 and only clear HIGHER after 9 is counted for both LOWER and HIGHER. I don't want to count 10 already, and then clear it.

More so, I would not want to clear the counter just because I have registered an illegal value. I would want to continue counting correctly.

This is what I mean: I wouldn't want to count up to say 50 and then clear it because I have registered an undesired value. I would rather keep an updated previous value in a separate register so that on the event of registering an undesired value, I would then add 2 to the updated previous value and assign it as the new value. What this helps do is avoid clearing and going back to 0.

This part as described would have been a bit tasky for the purpose of just learning how to write a BCD-based counter and so I omitted it.

- - - Updated - - -
Besides that what happens if LOWER or HIGHER ends up with 1010 through 1111 in it? It gets stuck forever.

ad-see said:
I prefer counting when less than the end value and clearing otherwise.
I would only clear if both LOWER and HIGHER register an illegal value. Otherwise, I would update one register with the other as necessary.
 

In this case, it is easier to write an if/else for LOWER, and then a second if/elsif for HIGHER. That makes it clear that HIGHER isn't used in the logic for LOWER, and that LOWER is used in the logic for HIGHER. It also gets rid of some duplicate code.

It is up to you if you would create a variable for (LOWER >= 9) to avoid duplicating the expression multiple times. The expression is simple and unlikely to change.
 

In this case, it is easier to write an if/else for LOWER, and then a second if/elsif for HIGHER. That makes it clear that HIGHER isn't used in the logic for LOWER, and that LOWER is used in the logic for HIGHER. It also gets rid of some duplicate code.

I see what you mean. Thanks on that.

Thanks ads-ee.
 

Thanks for your responses everyone. I am having a very hard time in designing. Can someone please refer a good source where I can start?
 

I would only clear if both LOWER and HIGHER register an illegal value. Otherwise, I would update one register with the other as necessary.

This statement was an oversight. I meant to say that I would only clear if the UPDATED PREVIOUS VALUE REGISTER or either HIGHER or LOWER registered an illegal value. Otherwise, I would updated HIGHER or LOWER with the UPDATED PREVIOUS VALUE or vice versa.

dzafar,
I began with textbooks on digital systems and VHDL. I read several of them , then went on to VHDL-specific textbooks. Then...

It more like depends on what you perceive to be what you are lacking, or what you need. I believe you just have to pay attention to yourself.
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top