Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Honored Contributor I
3,299 Views

BCD counter vhdl code

I am a newbie quartus user.. please help me thanks 

http://i54.tinypic.com/2zp2p3p.png  

This is my written code: 

 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.numeric_std.all; 

entity d4 is 

port (reset, sensor, load :in std_logic; 

p :in std_logic_vector (5 downto 0); 

led_on :out std_logic; 

q :out std_logic_vector (5 downto 0)); 

end d4; 

 

architecture flow of d4 is 

signal count_sig : unsigned (5 downto 0); 

signal load_sig : unsigned (5 downto 0); 

begin 

process (sensor, reset, load, p) 

begin 

if (reset = '1') then 

count_sig <= "000000"; 

elsif rising_edge (sensor) then 

if (count_sig = 32) then 

count_sig <= "000000"; 

else 

count_sig <= count_sig + 1; 

if (load = '0') then 

count_sig <= load_sig; 

else 

count_sig <= count_sig + 1; 

 

end if; 

end if; 

end if; 

end process; 

 

q <= std_logic_vector (count_sig); 

end flow;  

 

 

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

 

I did not add LED_ON in the code because i don't know the correct way to to put in the LED, always getting error when i try to put in LED code..  

 

and i can't make P to activate Q when load is low. 

 

i don't know what i am talking about too. Please help me ! appreciate if u do so  

:confused:
0 Kudos
16 Replies
Honored Contributor I
242 Views

LED_ON is just an output, you can assign it anywhere you want: 

 

LED_on <= '1'; 

or LED_on <= some_other_signal; 

 

or 

 

if something_happened then 

led_on <= '1'; 

else 

led_on <= '0'; 

end if; 

 

etc.
0 Kudos
Honored Contributor I
242 Views

is LED_ON a predefined output?  

It's the second time i read about it.
0 Kudos
Honored Contributor I
242 Views

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity d4 is port (reset, sensor, load :in std_logic; p :in std_logic_vector (5 downto 0); led_on :out std_logic; q :out std_logic_vector (5 downto 0)); end d4; architecture flow of d4 is signal count_sig : unsigned (5 downto 0); signal load_sig : unsigned (5 downto 0); begin process (sensor, reset, load, p) begin if (reset = '1') then count_sig <= "000000"; elsif rising_edge (sensor) then if (count_sig = 32) then LED_ON <= '1'; count_sig <= "000000"; else LED_ON <= '0'; count_sig <= count_sig + 1; if (load = '0') then count_sig <= p; end if; end if; end if; end process; q <= std_logic_vector (count_sig); end flow; 

 

Try this.
0 Kudos
Honored Contributor I
242 Views

 

--- Quote Start ---  

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity d4 is port (reset, sensor, load :in std_logic; p :in std_logic_vector (5 downto 0); led_on :out std_logic; q :out std_logic_vector (5 downto 0)); end d4; architecture flow of d4 is signal count_sig : unsigned (5 downto 0); signal load_sig : unsigned (5 downto 0); begin process (sensor, reset, load, p) begin if (reset = '1') then count_sig <= "000000"; elsif rising_edge (sensor) then if (count_sig = 32) then LED_ON <= '1'; count_sig <= "000000"; else LED_ON <= '0'; count_sig <= count_sig + 1; if (load = '0') then count_sig <= p; end if; end if; end if; end process; q <= std_logic_vector (count_sig); end flow;Try this. 

--- Quote End ---  

 

 

Error (10476): VHDL error at d4.vhdl(27): type of identifier "p" does not agree with its usage as UNSIGNED type 

 

thanks for assisting, it's not only the LED that i don't know about .. i feel that my code is not written properly and i can't find out the reason because i was not taught properly.. this one is way beyond my level
0 Kudos
Honored Contributor I
242 Views

 

--- Quote Start ---  

Error (10476): VHDL error at d4.vhdl(27): type of identifier "p" does not agree with its usage as UNSIGNED type 

--- Quote End ---  

 

Truely. You need a type cast when assigning std_logic_vector to unsigned. Why don't you simply correct it and proceed.
0 Kudos
Honored Contributor I
242 Views

 

--- Quote Start ---  

Truely. You need a type cast when assigning std_logic_vector to unsigned. Why don't you simply correct it and proceed. 

--- Quote End ---  

 

 

how do u do that lol .. sry i am really a noob my lecturer didn't taught us trial and error..
0 Kudos
Honored Contributor I
242 Views

You really should have a VHDL tutorial or text book to get some ideas for trial and error. And furthermore learn about the basic concepts of the language and HDL programming in general. 

 

For compatible types, e.g. bit vectors of same length, a typecast is simple. You already have one in your code 

q <= std_logic_vector (count_sig); 

Trial and error actually has a good chance for a hit with the opposite direction 

count_sig <= unsigned(p);
0 Kudos
Honored Contributor I
242 Views

expected result  

http://i54.tinypic.com/2zp2p3p.png  

my result 

http://i51.tinypic.com/al6iyc.png  

 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.numeric_std.all; 

entity d4 is 

port (reset, sensor, load :in std_logic; 

p :in std_logic_vector (5 downto 0); 

led_on :out std_logic; 

q :out std_logic_vector (5 downto 0)); 

end d4; 

 

architecture flow of d4 is 

signal count_sig : unsigned (5 downto 0); 

signal load_sig : unsigned (5 downto 0); 

begin 

process (sensor, reset, load, p) 

begin 

if (reset = '1') then 

count_sig <= "000000"; 

elsif rising_edge (sensor) then 

if (count_sig = 32) then 

led_on <= '0'; 

count_sig <= "010000"; 

else 

led_on <= '1'; 

count_sig <= count_sig + 1; 

if (load = '0') then 

count_sig <= unsigned(p); 

 

end if; 

end if; 

end if; 

end process; 

 

q <= std_logic_vector (count_sig); 

end flow; 

 

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

When load is '0' on P=2 .. q is not starting from 2... why???  

 

btw LED is kind of correct now. no idea why is it '0' when q = 0.. 

 

sorry for the troubles guys please help me ..
0 Kudos
Honored Contributor I
242 Views

Basically the simulation result is doing what your code commands, which is different from the above shown reference waveform. But as you have a working code now, you are on the right track. 

 

A first, possibly less obvious problem is brought up by performing a functional rather than a timing simulation. This causes the load signal to be ignored, if it's deasserted on the rising edge of the sensor signal. This detail suggests, that the reference waveform is a timing simulation. For small designs, I would generally suggest a timing simulation, because it shows the real hardware behaviour. By slightly increasing the pulse width of load, it should work also in functional simulation. 

 

The second point is about initial signal states. All registers are initialized to zero by default on power-up, unless you alllow power-up don't care as a synthesis option. This means, that the led output signal must be explicitely set to '1' in your code, preferably under the reset condition.  

 

The third, general point is about the counter operation. In the reference waveform, the counter is counting from 31 to 0, which suggests a 5 bit wide counter, not 6 bit as in your code. I don't know if the exercise is explicitely stating the width of input and output signals. A 5 bit counter would automatically overflow from 31 to 0 without writing it in your code. But it's not bad to write the condition if count = 31 then explicitely. And it's required to trigger the led action.  

 

Finally, how about the led signal? Strictly spoken, the reference waveform is not an exact specification, because it doesn't say, what happens, when the next 32 events are counted, but the most simple assumption is to repeat the LED action. In this case, the led output can be understood as a counter overflow signal, delayed by one cycle. You need an additional flag signal (a register) to implement it in your code.  

 

I would write it like this. I left the counter bit width open in this place by using a different zero syntax.  

if count_sig = 31 then led_flag <= '1'; count_sig <= (others => '0'); else led_flag <= '0'; count_sig <= count_sig + 1; end if; led <= NOT led_flag;
0 Kudos
Honored Contributor I
242 Views

thanks for ur explanation and assist.. understood a lot!  

"By slightly increasing the pulse width of load, it should work also in functional simulation." could you explain it more ? how do u increase the pulse width of load. 

 

http://i53.tinypic.com/2lbkkrt.png  

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.numeric_std.all; 

entity d4 is 

port (reset, sensor, load :in std_logic; 

p :in std_logic_vector (4 downto 0); 

led_on :out std_logic; 

q :out std_logic_vector (4 downto 0)); 

end d4; 

 

architecture flow of d4 is 

signal count_sig : unsigned (4 downto 0); 

 

 

begin 

process (sensor, reset, load, p) 

begin 

if (reset = '1') then 

count_sig <= "00000"; 

elsif rising_edge (sensor) then 

count_sig <= count_sig + 1; 

if (count_sig = 31) then 

led_on <= '1'; 

count_sig <= (others => '0'); 

else 

led_on <= '0'; 

count_sig <= count_sig + 1; 

if (load = '0') then 

count_sig <= unsigned(p); 

 

 

end if; 

end if; 

end if; 

end process; 

 

q <= std_logic_vector (count_sig); 

end flow; 

 

looking better now. 

but  

if (load = '0') then 

count_sig <= unsigned(p); 

this code seems useless.. 

 

When load is '0' on P=2 .. q is not starting from 2... or when load is '0' on P=20.. q is not starting from 20, like shown in the correct stimulation. please enlighten me. i have been saying countless times of thank you but really i appreciate ur help.. 

 

happy lunar new year to all of u!
0 Kudos
Honored Contributor I
242 Views

The code seems right: But you have twice "count_sig <= count_sig + 1;" in the code. But i don't think thats gonna affect the process.  

 

I should try to adjust the test bench. Make load low for longer than a half a clk period. Make it low for 2 clk periods. Load works on a rising edge and load = '0'.
0 Kudos
Honored Contributor I
242 Views

I told the reason for load not working in my previous post. Read it again. Or follow the above suggestion, but the waveform would be slightly different from the reference.  

 

Also the led output is coming one cycle too soon, and with wrong polarity compared to the reference waveform. I also told a suggestion for this point. 

 

 

--- Quote Start ---  

But you have twice "count_sig <= count_sig + 1;" in the code. But i don't think thats gonna affect the process. 

--- Quote End ---  

 

Right, only the last assignment in a process wins, this property is also utilized for the load case. But the double assignment should be removed for clarity.
0 Kudos
Honored Contributor I
242 Views

FvM and woody allen thanks for ur great help ! i hv got it working like it's suppose to already! thanks !

0 Kudos
Honored Contributor I
242 Views

oops a minor problem. 

 

http://i53.tinypic.com/35d6ek8.png  

how to i fix this ? 

 

 

 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.numeric_std.all; 

entity d4 is 

port (reset, sensor, load :in std_logic; 

p :in std_logic_vector (4 downto 0); 

led_on :out std_logic; 

q :out std_logic_vector (4 downto 0)); 

end d4; 

 

architecture flow of d4 is 

signal count_sig : unsigned (4 downto 0); 

signal led_flag : std_logic; 

 

 

begin 

process (sensor, reset, load, p) 

begin 

if (reset = '1') then 

count_sig <= "00000"; 

elsif rising_edge (sensor) then 

if count_sig = 31 then 

led_flag <= '1'; 

count_sig <= (others => '0'); 

else 

led_flag <= '0'; 

count_sig <= count_sig + 1; 

led_on <= not led_flag; 

if (load = '0') then 

count_sig <= unsigned(p); 

 

 

end if; 

end if; 

end if; 

end process; 

 

q <= std_logic_vector (count_sig); 

end flow;
0 Kudos
Honored Contributor I
242 Views

if (reset = '1') then count_sig <= "00000"; led <= '1'; led_flag <= '0'; elsif rising_edge (sensor) then

0 Kudos
Honored Contributor I
242 Views

ok thanks...

0 Kudos