Counter help

S

salman sheikh

Guest
Hello All,

I am trying to build a 21 bit delay that operates like this. When an
enable signal becomes high, start counting and after 20 clock pulses,
output a high pulse for one clock cycle. The code below does not count
correctly. Why? Can i not have a count inside the process statement or
does it have to be in the clock process with some enables in the other
process?


Salman


---

entity Delay21 is
port ( ena : in std_logic;
output : out std_logic;
rst : in std_logic ;
clk : in std_logic );
end entity;

architecture arch of Delay21 is

signal count : integer range 0 to 21;
type state is (idle, increment, done);
signal current_state, next_state : state;

begin

process(rst, clk)
begin
if rst = '1' then
current_state <= idle;
elsif clk'event and clk='1' then
current_state <= next_state;
end if;
end process;

process (ena, current_state)
begin
case (current_state) is
when idle =>
output <= '0';
if ena = '1' then
count <= 0;
next_state <= increment;
else
next_state <= idle;
end if;

when increment =>
output <= '0';
count <= count + 1;
if count = 20 then
next_state <= done;
else
next_state <= increment;
end if;

when done =>
output <= '1';
next_state <= idle;
end case;
end process;

end architecture;
 
Why not generate a single pulse (one clock cycle wide) from the enable
signal going high (3 flip flops and a three input and gate and an inverter),
and then delay that using a SRL16 (if you are using s Xilinx device) or a
series of flip flops to create the number of delay cycles required after the
pulse. Generating the pulse with take 3 cylces anyway (see code below for a
simple pulse generator.

Jason

library ieee;
use ieee.std_logic_1164.all;

entity pulse_gen is
port(
input : in std_logic;
reset : in std_logic;
clk : in std_logic;
pulse : out std_logic
);
end pulse_gen;

architecture rtl of pulse_gen is

signal q1,q2,q3 : std_logic;

begin

process (reset, clk) begin
if reset = '1' then
q1 <= '0';
q2 <= '0';
q3 <= '0';
pulse <= '0';
elsif rising_edge(clk) then
q1 <= input;
q2 <= q1;
q3 <= q2;
pulse <= q1 and q2 and (not q3);
end if;
end process;

end rtl;

"salman sheikh" <sheikh@pop500.gsfc.nasa.gov> wrote in message
news:bthcte$kea$1@skates.gsfc.nasa.gov...
Hello All,

I am trying to build a 21 bit delay that operates like this. When an
enable signal becomes high, start counting and after 20 clock pulses,
output a high pulse for one clock cycle. The code below does not count
correctly. Why? Can i not have a count inside the process statement or
does it have to be in the clock process with some enables in the other
process?


Salman


---

entity Delay21 is
port ( ena : in std_logic;
output : out std_logic;
rst : in std_logic ;
clk : in std_logic );
end entity;

architecture arch of Delay21 is

signal count : integer range 0 to 21;
type state is (idle, increment, done);
signal current_state, next_state : state;

begin

process(rst, clk)
begin
if rst = '1' then
current_state <= idle;
elsif clk'event and clk='1' then
current_state <= next_state;
end if;
end process;

process (ena, current_state)
begin
case (current_state) is
when idle =
output <= '0';
if ena = '1' then
count <= 0;
next_state <= increment;
else
next_state <= idle;
end if;

when increment =
output <= '0';
count <= count + 1;
if count = 20 then
next_state <= done;
else
next_state <= increment;
end if;

when done =
output <= '1';
next_state <= idle;
end case;
end process;

end architecture;
 
salman sheikh wrote:


process (ena, current_state)
begin
case (current_state) is
when idle =
output <= '0';
if ena = '1' then
count <= 0;
next_state <= increment;
else
next_state <= idle;
end if;

when increment =
output <= '0';
count <= count + 1;
if count = 20 then
next_state <= done;
else
next_state <= increment;
end if;

when done =
output <= '1';
next_state <= idle;
end case;
end process;

You mixed combinational and synchronous logic.
For the signal "nextstate" everything is fine, because it can be
combinational logic.

Because you did not put "count" into the sensitivity list, the following
should happen:
In

count <= count + 1;
count gets a new value in the NEXT delta cycle. But this process is
activated only if "ena" or "current_state" changes, what will be later.

Therefor

if count = 20 then
evaluates the value of count in the ACTUAL delty cycle.

But if you put "count" into the sensitivity list,

count <= count + 1;
leads to an infinite loop, because every delta cycle count is incremented.


Soluting idea: "count" is a counter and therefor has to be a flipflop.
The easiest way to achieve this without changing the code too much would be:

process(clk)
begin
if falling_edge(clock) then -- state machine works on rising_edge!
if (current_state=increment) then
count = count + 1;
else count = 0;
end if;
end if;
end process;

(And remove all write access to "count" in your nextstate-logic.)


Note: Because of using both clock-edges, timing may be critical during
the nextstate-logic.


Ralf
 

Welcome to EDABoard.com

Sponsor

Back
Top