2 counters, counting states of Bit stream

  • Thread starter brandon.spiteri
  • Start date
B

brandon.spiteri

I need to implement 2 counters that counts 1's and 0's of an incoming bit stream.
However I have a problem that not even the clock is generated on ModelSim and all the signals
are labeled as 'no data'. Is there a problem in my code or is it related to some configuration or settings?

This is my code;

--bit_counter.vhd

LIBRARY ieee;
-- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
use ieee.std_logic_1164.all;

-- SIGNED and UNSIGNED types, and relevant functions
use ieee.numeric_std.all;


entity bit_counter is

port(Start : in std_logic := '0' ; --was in
Reset : in std_logic := '1';
Clock : in std_logic := '0';
Bit_stream : in std_logic := '0';

Q_H, Q_L : out std_logic_vector (3 downto 0)
);


end entity bit_counter;

architecture RTL of bit_counter is

--type state_type is (IDLE, Bit_is_high, Bit_is_low);

--signal initBitH, initBitL, BitH, BitL : std_logic;
signal cnt_L, cnt_H : integer range 0 to 15;


begin

count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)

begin

Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));

if(Reset = '0') then
cnt_H <= 0;
cnt_L <= 0;

elsif (Start = '1') then
if(rising_edge(Clock)) then

if (Bit_stream = '1') then
cnt_H <= cnt_H + 1;
cnt_L <= cnt_L;
elsif (Bit_stream = '0') then
Cnt_H <= Cnt_H;
Cnt_L <= Cnt_L + 1;
end if;
end if;
end if;



end process;

end architecture RTL;

--bit_counter_test.vhd

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

entity bit_counter_test is
end Entity bit_counter_test;

Architecture behavioral of bit_counter_test is

Signal Bit_stream, Clock : std_logic := '0';
Signal Reset_count, Start_count : std_logic := '1';
Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');

begin

UUT : entity work.bit_counter
port map (

Bit_stream => Bit_stream,
Start => Start_count,
Reset => Reset_count,
Clock => Clock);


CLK_process :process
begin
for C in 30 downto 0 loop
Clock <= NOT Clock after 5ns;
end loop;
end process;

Signals : process

Begin

for I in 30 downto 0 loop
wait for 10 ns;
Start_count <= '1';
Reset_count <= '1';
Bit_stream <= '0';


end loop ;

wait for 10 ns;

for J in 30 downto 0 loop
wait for 10 ns;
Start_count <= '1';
Reset_count <= '1';
Bit_stream <= '1';

end loop ;

wait;
end process;



end Architecture behavioral;

In the past I already managed to simulate combinational logic with model sim so clock wasn't involved. It seams that the problem is I am not using the clock correctly..
 
G

goouse99

Am Donnerstag, 6. Juni 2013 03:32:16 UTC+2 schrieb Brandon Spiteri:
I need to implement 2 counters that counts 1's and 0's of an incoming bit stream.

However I have a problem that not even the clock is generated on ModelSim and all the signals

are labeled as 'no data'. Is there a problem in my code or is it related to some configuration or settings?



This is my code;



--bit_counter.vhd



LIBRARY ieee;

-- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions

use ieee.std_logic_1164.all;



-- SIGNED and UNSIGNED types, and relevant functions

use ieee.numeric_std.all;





entity bit_counter is



port(Start : in std_logic := '0' ; --was in

Reset : in std_logic := '1';

Clock : in std_logic := '0';

Bit_stream : in std_logic := '0';



Q_H, Q_L : out std_logic_vector (3 downto 0)

);





end entity bit_counter;



architecture RTL of bit_counter is



--type state_type is (IDLE, Bit_is_high, Bit_is_low);



--signal initBitH, initBitL, BitH, BitL : std_logic;

signal cnt_L, cnt_H : integer range 0 to 15;





begin



count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)



begin



Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));

Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));



if(Reset = '0') then

cnt_H <= 0;

cnt_L <= 0;



elsif (Start = '1') then

if(rising_edge(Clock)) then



if (Bit_stream = '1') then

cnt_H <= cnt_H + 1;

cnt_L <= cnt_L;

elsif (Bit_stream = '0') then

Cnt_H <= Cnt_H;

Cnt_L <= Cnt_L + 1;

end if;

end if;

end if;







end process;



end architecture RTL;



--bit_counter_test.vhd



library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use ieee.std_logic_unsigned.all;



entity bit_counter_test is

end Entity bit_counter_test;



Architecture behavioral of bit_counter_test is



Signal Bit_stream, Clock : std_logic := '0';

Signal Reset_count, Start_count : std_logic := '1';

Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');



begin



UUT : entity work.bit_counter

port map (



Bit_stream => Bit_stream,

Start => Start_count,

Reset => Reset_count,

Clock => Clock);





CLK_process :process

begin

for C in 30 downto 0 loop

Clock <= NOT Clock after 5ns;

end loop;

end process;



Signals : process



Begin



for I in 30 downto 0 loop

wait for 10 ns;

Start_count <= '1';

Reset_count <= '1';

Bit_stream <= '0';





end loop ;



wait for 10 ns;



for J in 30 downto 0 loop

wait for 10 ns;

Start_count <= '1';

Reset_count <= '1';

Bit_stream <= '1';



end loop ;



wait;

end process;







end Architecture behavioral;



In the past I already managed to simulate combinational logic with model sim so clock wasn't involved. It seams that the problem is I am not using the clock correctly..

Hi Brandon.
so many loops... you may end up in a knot. :)

Think about what you are doing in your clock process:
You have a signal assignment that gets overwritten a number of times in the loop.
The after statement will just add one event to the event list, but this is not accumulating. It will just be overwritten.
Instead you may use this:
Clock <= NOT Clock;
wait for 5ns;

Hint:
The loops in your stimuli process can be simplified.
after you set some variable you can just use
wait for 30*10ns; -- 30 can be replaced by any other number.
To avoid problems that may arise when you have signal changes on the rising clock edge, you can either use an initial delay that puts the signal chanses clearly out of phase :
e.g. wait for 3 ns; -- put this in the beginning of your stimuli list.

There are other methods like implementing a clock counter and using a synchronous process with a case to select the time for signal assignments:

sig1 <= '0'; --default assignment
case clockcount is
when 5 => sig1<= '1';
when 7 to 9 => sig1<= '1';
-- and so on


Another thing:
aside from the asynchronous reset you shouldn't have statements outside the synchronous parts.

The assignments for Q_L and Q_H can be placed outside the process, thus becoming concurrent assignments.


elsif (Start = '1') then
if(rising_edge(Clock)) then

should be rewritten as:
elsif(rising_edge(Clock)) then
if (Start = '1') then

Ranged integers work well, but there may come a time where you want to handle more than 32 bits. While you are using numeric_std anyway you could also declare the counting signals like this:
signal cnt_L, cnt_H : unsigned(3 downto 0);

This way your type conversions become shorter and you never get into the hazzle of "integer overflow errors". The unsigned type would simply roll over to 0.
Still adding integers to unsigned type signals works, so no further code changes are needed.

Have a nice simulation
Eilert
 
B

Brandon Spiteri

Thanks a lot for your help. I managed to simulate the test bench and I got what I wanted.

Now I need to implement this on an FPGA. I have the board driver and I modified it accordingly like
I did for other small projects.

My friend told me that to implement it on an FPGA, the vhdl code needs some minor tweaking but I do not know what he was referring to. In the board driver I used debouncing for the 2 tact switches; Bit_stream and clock.

Can you guide me what tweaking is needed? thanks

This is my code;

--bit_counter.vhd

LIBRARY ieee;
-- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
use ieee.std_logic_1164.all;

-- SIGNED and UNSIGNED types, and relevant functions
use ieee.numeric_std.all;


entity bit_counter is

port(Start : in std_logic := '0' ; --was in
Reset : in std_logic := '1';
Clock : in std_logic := '0';
Bit_stream : in std_logic := '0';

Q_H, Q_L : out std_logic_vector (3 downto 0) := (others => '0')
);


end entity bit_counter;

architecture RTL of bit_counter is


signal cnt_L, cnt_H : integer range 0 to 15;

begin
Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));

count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)

begin

if(Reset = '0' ) then
cnt_H <= 0;
cnt_L <= 0;

elsif (rising_edge(Clock)) then
if(Start = '1') then

if (Bit_stream = '1') then
cnt_H <= cnt_H + 1 ;
cnt_L <= cnt_L ;


elsif (Bit_stream = '0') then
Cnt_L <= Cnt_L + 1 ;
Cnt_H <= Cnt_H ;

end if;
end if;
end if;


end process;

end architecture RTL;

--bit_counter_test.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use ieee.std_logic_unsigned.all;


entity bit_counter_test is
end Entity bit_counter_test;

Architecture behavioral of bit_counter_test is

Signal Bit_stream, ext_Clock : std_logic := '0';
Signal Reset_count, Start_count : std_logic := '1';
Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
Signal Endsim : std_logic := '0';
begin

UUT : entity work.bit_counter
port map (

Bit_stream => Bit_stream,
Start => Start_count,
Reset => Reset_count,
Clock => ext_Clock,
Q_L => Q_L,
Q_H => Q_H);


CLK_process :process
begin
if(EndSim = '0') then
ext_Clock <= NOT ext_Clock;
wait for 2ns;
end if;
end process;

Signals : process

Begin

wait for 0.5 ns;
Start_count <= '1';
Reset_count <= '1';

for I in 15 downto 0 loop
Bit_stream <= '1';
wait for 4 ns;
Bit_stream <= '0';
wait for 4 ns;

end loop ;

EndSim <= '1';
wait;
end process;

end Architecture behavioral;

--boarddriver.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.QuantumBaseSupport.all;

entity BoardDriver is
Port (
BUTTON : in STD_LOGIC_VECTOR(3 downto 0);
DIP : in STD_LOGIC_VECTOR(7 downto 0);
RESET : in STD_LOGIC; --Active Low
CLK0 : in STD_LOGIC; --20MHz input
CLK2 : in STD_LOGIC;

-- Output ports
COM : out STD_LOGIC_VECTOR(3 downto 0);
FND_EN : out STD_LOGIC;
LED : out STD_LOGIC_VECTOR(7 downto 0);
SEGMENTS : out STD_LOGIC_VECTOR(7 downto 0);
EXPANSION : out STD_LOGIC_VECTOR(26 downto 0)
);
end BoardDriver;

architecture RTL of BoardDriver is

alias Button1 is BUTTON(0);
alias Button2 is BUTTON(1);
alias Button3 is BUTTON(2);
alias Button4 is BUTTON(3);

alias DIP1 is DIP(0);
alias DIP2 is DIP(1);
alias DIP3 is DIP(2);
alias DIP4 is DIP(3);
alias DIP5 is DIP(4);
alias DIP6 is DIP(5);
alias DIP7 is DIP(6);
alias DIP8 is DIP(7);

alias LED1 is LED(0);
alias LED2 is LED(1);
alias LED3 is LED(2);
alias LED4 is LED(3);
alias LED5 is LED(4);
alias LED6 is LED(5);
alias LED7 is LED(6);
alias LED8 is LED(7);

signal ButtonDB_stream : std_logic;
signal ButtonDB_clk : std_logic;

begin

EXPANSION <= (others => 'Z');

DeBounce_stream : entity work.SwDebounce
port map( Clock => CLK0,
Reset => Reset,
Input => Button1,
Debounced_out => ButtonDB_stream
);
DeBounce_clk : entity work.SwDebounce
port map( Clock => CLK0,
Reset => Reset,
Input => Button1,
Debounced_out => ButtonDB_clk
);
Count_Bits: entity work.bit_counter
Port map(
Reset => Reset,
Clock => ButtonDB_clk,
Bit_stream => ButtonDB_stream,
Start => DIP1,
Q_L => LED (3 downto 0),
Q_H => LED (7 downto 4)

);

end architecture RTL;
 
A

Andy

A few more tips...

General:

You don't need () around conditions in if-statements.

bit_counter:

Remove all but clock and reset from sensitivity list.

Remove assignments to self for clk_L and Clk_H.

You can combine if-statements for rising_edge() and start:

if rising_edge(clock) and start = '1' then

Testbench:

Insert an "else wait;" statement before "end if;" in your clock driver process. This keeps it from running in an endless, zero-delay loop when endsim becomes '1'.

But I usually drive the clock from a concurrent assignment:

ext_clock <= not ext_clock after 2 ns when endsim = '0';

Pace the testbench by using "wait for falling_edge(clk);" instead of 'wait for 4 ns;" This keeps it syncrhonized to the clock no matter what.

Andy
 
R

rickman

Thanks a lot for your help. I managed to simulate the test bench and I got what I wanted.

Now I need to implement this on an FPGA. I have the board driver and I modified it accordingly like
I did for other small projects.

My friend told me that to implement it on an FPGA, the vhdl code needs some minor tweaking but I do not know what he was referring to. In the board driver I used debouncing for the 2 tact switches; Bit_stream and clock.

Can you guide me what tweaking is needed? thanks

Tweaking for synthesis after simulation is not a good idea. If changes
are made to the code to be synthesized, it would need to be simulated
again to make sure nothing functional has changed.

The only thing I see that should be changed is your sensitivity list
that contains not only the clock and the async reset, but other inputs
to the process. These should not be included in the sensitivity list
because of how the sensitivity list works. Any change to any of the
signals in the list cause the process to run. There are cases where
this will cause the simulation results to be different from the way the
synthesized hardware to work.

I think I see one mistake in your code. You use Button1 as input to
both debounce circuits. I assume one should be Button1 and the other
Button2?

I wouldn't change the use of parens in IF statements. They clearly
delineate the expression being evaluated just like using a period at the
end of a sentence. I also wouldn't worry about using assignments of
signals to themselves when you want the value of a FF to remain
unchanged. This is redundant since if nothing is specified it is
assumed that the signal will hold a value, but specifying it can make
some code more clear. In other words, it is a judgement call by the
author and I would never criticize this.

Rick
 
G

goouse99

Am Donnerstag, 6. Juni 2013 03:32:16 UTC+2 schrieb Brandon Spiteri:
I need to implement 2 counters that counts 1's and 0's of an incoming bit stream.

However I have a problem that not even the clock is generated on ModelSim and all the signals

are labeled as 'no data'. Is there a problem in my code or is it related to some configuration or settings?



This is my code;



--bit_counter.vhd



LIBRARY ieee;

-- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions

use ieee.std_logic_1164.all;



-- SIGNED and UNSIGNED types, and relevant functions

use ieee.numeric_std.all;





entity bit_counter is



port(Start : in std_logic := '0' ; --was in

Reset : in std_logic := '1';

Clock : in std_logic := '0';

Bit_stream : in std_logic := '0';



Q_H, Q_L : out std_logic_vector (3 downto 0)

);





end entity bit_counter;



architecture RTL of bit_counter is



--type state_type is (IDLE, Bit_is_high, Bit_is_low);



--signal initBitH, initBitL, BitH, BitL : std_logic;

signal cnt_L, cnt_H : integer range 0 to 15;





begin



count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)



begin



Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));

Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));



if(Reset = '0') then

cnt_H <= 0;

cnt_L <= 0;



elsif (Start = '1') then

if(rising_edge(Clock)) then



if (Bit_stream = '1') then

cnt_H <= cnt_H + 1;

cnt_L <= cnt_L;

elsif (Bit_stream = '0') then

Cnt_H <= Cnt_H;

Cnt_L <= Cnt_L + 1;

end if;

end if;

end if;







end process;



end architecture RTL;



--bit_counter_test.vhd



library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use ieee.std_logic_unsigned.all;



entity bit_counter_test is

end Entity bit_counter_test;



Architecture behavioral of bit_counter_test is



Signal Bit_stream, Clock : std_logic := '0';

Signal Reset_count, Start_count : std_logic := '1';

Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');



begin



UUT : entity work.bit_counter

port map (



Bit_stream => Bit_stream,

Start => Start_count,

Reset => Reset_count,

Clock => Clock);





CLK_process :process

begin

for C in 30 downto 0 loop

Clock <= NOT Clock after 5ns;

end loop;

end process;



Signals : process



Begin



for I in 30 downto 0 loop

wait for 10 ns;

Start_count <= '1';

Reset_count <= '1';

Bit_stream <= '0';





end loop ;



wait for 10 ns;



for J in 30 downto 0 loop

wait for 10 ns;

Start_count <= '1';

Reset_count <= '1';

Bit_stream <= '1';



end loop ;



wait;

end process;







end Architecture behavioral;



In the past I already managed to simulate combinational logic with model sim so clock wasn't involved. It seams that the problem is I am not using the clock correctly..

Hi Brandon,
one little question concerning your debouncer :
It is clocked with 20 MHz.
Does it have an internal counter to further reduce the sampling rate of the switch/button signals?
Otherwise you would take samples every 50ns and since debouncers normally have just a few stages the debouncing period then will be just a few hundred ns.
Switches/buttons tend to have bouncing times in the micro to milliseconds range.

So please check this before you are wondering about strange hardware behavior.

Have a nice synthesis
Eilert
 
B

Brandon Spiteri

I modified the sensitivity list as you specified and I had 8 warnings, one for each signal which I removed. But there was no errors. Is there a particular reason why we leave only Reset and Clock?

Can I eliminate the warnings? thanks for pointing out the button1 issue..

Regarding the self assigning to cnt_H and cnt_L, I was advised to do this to avoid extra memory elements. I do not know if this is true.
 
B

Brandon Spiteri

Hi Eilert,
thanks for pointing that out. I should have shown this file as well:
I think this is sufficient..

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.QuantumBaseSupport.all;

entity ClockDiv_Gen is
Generic( Source : integer := BoardClock; --20MHz
Destination : integer := 200); --100Hz
Port ( Reset : in STD_LOGIC;
Clock : in STD_LOGIC;
refresh_Clock : out STD_LOGIC);
end ClockDiv_Gen;

architecture RTL of ClockDiv_Gen is

begin
process(Reset,Clock)
variable Counter : integer range 0 to (Source/(Destination * 2)) := 0;
variable Cout : std_logic := '0';
begin
if (Reset = '0') then
refresh_Clock <= '0';
elsif rising_edge(Clock) then
Counter := Counter + 1;
if (Counter = (Source/(Destination * 2))) then
Cout := not Cout;
Counter := 0;
end if;
end if;
refresh_Clock <= Cout;
end process;

end RTL;
 
B

Brandon Spiteri

Hi Andy,
thanks for the tips :) I managed to implement them all. Exceptthe wait for falling_edge(clk); part.

Quartus is giving me the error when I try to compile:

Error (10511): VHDL Qualified Expression error at bit_counter_test.vhd(49):falling_edge type specified in Qualified Expression must match time type that is implied for expression by context

I think this is because ext_clock is declared as std_logic and this expression is expecting type time. I tried to modify the type to time in the general and testbech however, it seems that then I have to change all the logic of the code.. Is this the case?

thanks

Brandon
 
R

rickman

I modified the sensitivity list as you specified and I had 8 warnings, one for each signal which I removed. But there was no errors. Is there a particular reason why we leave only Reset and Clock?

I can't say since I don't know what the errors are. They aren't because
the signals belong in the sensitivity list.

Can I eliminate the warnings? thanks for pointing out the button1 issue..

What are the errors?

Regarding the self assigning to cnt_H and cnt_L, I was advised to do this to avoid extra memory elements. I do not know if this is true.

That is only true for combinatorial logic processes. This process is
sequential, no? When you write, "elsif (rising_edge(Clock)) then", you
are describing a register. All of the signals assigned inside of this
IF will be remembered in FFs regardless.

If you have a combinatorial process without an edge or level
sensitivity, you want all of the inputs (signals on the right side of
the assignments) in the sensitivity list (or you can just use "all" in
VHDL 2008 or later) and you need to make sure signals that are assigned
values are assigned values for all conditions to avoid generating
registers. Inadvertent latches are not uncommon.

Does that make sense?
 
R

rickman

Hi Andy,
thanks for the tips :) I managed to implement them all. Except the wait for falling_edge(clk); part.

Quartus is giving me the error when I try to compile:

Error (10511): VHDL Qualified Expression error at bit_counter_test.vhd(49): falling_edge type specified in Qualified Expression must match time type that is implied for expression by context

I think this is because ext_clock is declared as std_logic and this expression is expecting type time. I tried to modify the type to time in the general and testbech however, it seems that then I have to change all the logic of the code.. Is this the case?

How about showing the code? I expect this is something in a test bench
since I can't imagine time and a falling_edge spec would be mixed in
synthesized code.
 
B

Brandon Spiteri

How about showing the code? I expect this is something in a test bench

since I can't imagine time and a falling_edge spec would be mixed in

synthesized code.



--



Rick

The test bench is the same one in my first post. The warnings are:

Warning (10492): VHDL Process Statement warning at bit_counter.vhd(43): signal "Start" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
 
I

Ilya Kalistru

пÑтница, 7 Ð¸ÑŽÐ½Ñ 2013 г., 11:12:17 UTC+4 пользователь Brandon Spiteri напиÑал:
Hi Eilert,

thanks for pointing that out. I should have shown this file aswell:

I think this is sufficient..



library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;

use work.QuantumBaseSupport.all;



entity ClockDiv_Gen is

Generic( Source : integer := BoardClock; --20MHz

Destination : integer := 200); --100Hz

Port ( Reset : in STD_LOGIC;

Clock : in STD_LOGIC;

refresh_Clock : out STD_LOGIC);

end ClockDiv_Gen;



architecture RTL of ClockDiv_Gen is



begin

process(Reset,Clock)

variable Counter : integer range 0 to (Source/(Destination * 2)) := 0;

variable Cout : std_logic := '0';

begin

if (Reset = '0') then

refresh_Clock <= '0';

elsif rising_edge(Clock) then

Counter := Counter + 1;

if (Counter = (Source/(Destination * 2))) then

Cout := not Cout;

Counter := 0;

end if;

end if;

refresh_Clock <= Cout;

end process;



end RTL;

Are you use refresh_Clock for clocking your scheme? I don't think that is agood idea. Xilinx prohibit this technic. I think you should use dedicated primitives to clock generating that use dedicated clock nets.

If I can't use clock primitives or I don't want it, I use a simple entity that generate strobe signal that '0' several clock periods and then '1' one period and so on.
Then I use it

if (rising_edge(Clock)) and (strobe = '1') then
do_what_you_want;
end if;

This strobe signal reduce speed of do_what_you_want code without changing of frecuency of Clock.
 
R

rickman

The test bench is the same one in my first post. The warnings are:

Warning (10492): VHDL Process Statement warning at bit_counter.vhd(43): signal "Start" is read inside the Process Statement but isn't in the Process Statement's sensitivity list

Sorry, there is no way I can relate "line 43" to the contents of your
previous post. You need to post the text in a format that preserves the
lines and replace tabs with spaces so the text isn't all skewed across
the screen. I'm happy to help, but I don't want to have to dig the info
out of your posts. Or repost the code pointing to the offending line.

Looking at the original code I do see a couple of lines at the beginning
of the count: process (good that you name your processes) that I think
should not be there.

Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));

These are in the clocked process, but not inside the reset or the
clocked clauses and so are combinatorial statements. They will not
function in simulation the way they will work in the hardware. Move
them outside of the process maybe? I'm not sure what your intent is
with these. Looking at the code I think they need to be concurrent
statements outside of the clocked process. That may be confusing the
tools.

Oh, I see the problem... another problem. You have swapped the enable
and the clock edge test. The enable (Start = '1') needs to be inside
the clock test clause.

elsif (rising_edge(Clock)) then
if (Start = '1') then
...
 
B

Brandon Spiteri

" The enable (Start = '1') needs to be inside
the clock test clause. " That solved the problem :) .. thanks a lot. Below is my modified code;



LIBRARY ieee;

use ieee.std_logic_1164.all;


use ieee.numeric_std.unsigned;

use IEEE.std_logic_unsigned.all;

entity bit_counter is

port(Start : in std_logic := '0' ; --was in
Reset : in std_logic := '1';
Clock : in std_logic := '0';
Bit_stream : in std_logic := '0';

Q_H, Q_L : out std_logic_vector (3 downto 0) := (others => '0')
);


end entity bit_counter;

architecture RTL of bit_counter is

signal cnt_L, cnt_H : STD_LOGIC_VECTOR (3 downto 0) := "0000";

begin

Q_H <= Cnt_H;
Q_L <= Cnt_L;

count: process(Reset, Clock)

begin

if(Reset = '0' ) then
cnt_H <= "0000";
cnt_L <= "0000";

elsif (rising_edge(Clock)) then


if (start = '1' and Bit_stream = '1') then
cnt_H <= cnt_H + 1 ;
cnt_L <= cnt_L ;


elsif (start = '1' and Bit_stream = '0') then
Cnt_L <= Cnt_L + 1 ;
Cnt_H <= Cnt_H ;

end if;
end if;


end process;

end architecture RTL;

_________________________________________________________________________________________________

Regarding the test bench code below, do you think there is a better way to test my above code?
Do you think this is sufficient?

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use ieee.std_logic_unsigned.all;


entity bit_counter_test is
end Entity bit_counter_test;

Architecture behavioral of bit_counter_test is

Signal Bit_stream, ext_Clock : std_logic := '0';
Signal Reset_count, Start_count : std_logic := '1';
Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
Signal Endsim : std_logic := '0';
begin

UUT : entity work.bit_counter
port map (

Bit_stream => Bit_stream,
Start => Start_count,
Reset => Reset_count,
Clock => ext_Clock,
Q_L => Q_L,
Q_H => Q_H);


CLK_process :process
begin
if(EndSim = '0') then
ext_Clock <= NOT ext_Clock;
wait for 2ns;
else wait;
end if;
end process;

Signals : process

Begin

wait for 0.5 ns;
Start_count <= '1';
Reset_count <= '1';

for I in 18 downto 0 loop
Bit_stream <= '1';
wait for 4 ns;
Bit_stream <= '0';
wait for 4 ns;

end loop ;

Reset_count <= '0';
Start_count <= '1';
wait for 4 ns;
Reset_count <= '1';

for J in 8 downto 0 loop
Bit_stream <= '1';
wait for 4 ns;
Bit_stream <= '0';
wait for 4 ns;
end loop;

Start_count <= '0';
wait for 20 ns;
Start_count <= '1';

for K in 8 downto 0 loop
Bit_stream <= '1';
wait for 4 ns;
Bit_stream <= '0';
wait for 4 ns;
end loop;

EndSim <= '1';
wait;
end process;

end Architecture behavioral;
 
A

Andy

Brandon,

wait until falling_edge(clk); -- not wait "for"

Use "until" for conditions, "for" for time.

Andy
 
A

Andy

Rick,

This illustrates why I advise not using self assignments. People start using them because they heard it did something useful (and they even saw it on the interweb), and nobody really knows what purpose they serve. A self assignment will NEVER prevent inferrence of a latch, but it may actually createone!

These crutches keep new users from learning what actually causes a latch: Astorage device is inferred when the RTL description requires remembering avalue stored at a previous time (or delta-cycle). If that previous time was a previous clock edge, a register is inferred; if not, a latch is inferred.

When we read code, we assume that it is needed. That assumption is false inthis case. A self assignment is NEVER needed, but its presence implies it is needed. Otherwise, why would the author have typed it? If you want to leave it in for misguided self-documentation, at least comment it as unnecessary.

BTW, I use "if" and "then" (also if/generate, while/loop, or when/else) to clearly delineate a conditional expression. There may be parenthesis withinin the expression that do not delineate the entire expression, so parentheses alone do not provide that service. However, I sometimes use them to "help" the editor format multi-line conditional expressions more clearly.

But the latter is a matter of style, and less of substance (no additional operation by the simulator or the synthesis tool is implied). Many users assume that since other languages require it, it must be required in VHDL too,which is incorrect. Use them if you wish, but not because they are required, that's all.

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top