Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

error cascading 3 decoders/counters.

Status
Not open for further replies.

k2in5

Technical User
Oct 6, 2006
1
AU

need help cascading 3 decoders/counters.

I am using 3 * gal22v20's cant change them.
Clocks are all wired together and ripple out is connected to the enable of the next chip. After compiling the code the MSD decoder does not count correctly and appears to be taking 9/10 clk pluses to the enable causing it to run the fast. here is the original code there are no PCB error

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

entity segment_cnt is

port(

clk,mr,en,pause, clk_in :in std_logic;
segs :buffer std_logic_vector(6 downto 0);
clk_out ut std_logic;
rco : out std_logic
);

end segment_cnt;

architecture behav of segment_cnt is
begin

cnt_procrocess(clk, mr)
begin
if(mr='0') then segs <= "0000001";
elsif(clk'event and clk ='1') then
if (pause = '0') then segs <= segs;
elsif(en = '0' and pause = '1') then case segs is
when "0000001" => -- 0 goto 1
segs<="1001111";

when "1001111" => -- 1 goto 2
segs<="0010010";

when "0010010" => -- 2 goto 3
segs<="0000110";

when "0000110"=> -- 3 goto 4
segs<="1001100";

when "1001100" => -- 4 goto 5
segs<="0100100";

when "0100100" => -- 5 goto 6
segs<="0100000";

when "0100000" => -- 6 goto 7
segs<="0001111";

when "0000111" => -- 7 goto 8
segs<="0000000";

when "0000000" => -- 8 goto 9
segs<="0001100";

when others => -- 9 goto 0
segs<="0000001";

end case;
end if;
end if;
end process cnt_proc;
clk_out <= clk_in;
rco <= '1'when (segs = "0001100" and en ='0')else '0';
end behav;


I have tried to add a loop in the VHDL to loop 10 time before the count starts
here is that code and the error that it produced.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity segment_cnt is

port(

clk,mr,en,pause, clk_in :in std_logic;
segs :buffer std_logic_vector(6 downto 0);
count :buffer std_logic_vector(3 downto 0);
clk_out ut std_logic;
rco : out std_logic
);

end segment_cnt;

architecture behav of segment_cnt is
begin

cnt_procrocess(clk, mr)
begin
if(mr='0') then segs <= "0000001";
elsif(clk'event and clk ='1') then
if (pause = '0') then segs <= segs;
elsif(en = '0' and pause = '1') then

count <= count +1;
if (count ="1001") then
count <= "0000";
else count <= "0000";
end if;
end if;
if(count = "1001" and pause = '1') then case segs is
when "0000001" => -- 0 goto 1
segs<="1001111";

when "1001111" => -- 1 goto 2
segs<="0010010";

when "0010010" => -- 2 goto 3
segs<="0000110";

when "0000110"=> -- 3 goto 4
segs<="1001100";

when "1001100" => -- 4 goto 5
segs<="0100100";

when "0100100" => -- 5 goto 6
segs<="0100000";

when "0100000" => -- 6 goto 7
segs<="0001111";

when "0000111" => -- 7 goto 8
segs<="0000000";

when "0000000" => -- 8 goto 9
segs<="0001100";

when others => -- 9 goto 0
segs<="0000001";

end case;
end if;end if;
end process cnt_proc;
clk_out <= clk_in;
rco <= '1'when (segs = "0001100" and en ='0')else '0';
end behav;

Design optimization (dsgnopt)
Device fitting (pla2jed)
Error: Logic equation for signal count(3).AR is redefining a banked expression.
Error: Logic equation for signal count(2).AR is redefining a banked expression.
Error: Logic equation for signal count(1).AR is redefining a banked expression.
Error: Logic equation for signal count(0).AR is redefining a banked expression.

thanks
rob
 
Rob,

I would like very much to help you out, but I have to say I'm having some problems to understand the problem.

What I understand at this moment is that you have 3 GAL devices that you want to cascade. So I'm thinking you want to make a 3 digit (binary) counter correct?


First your first code extract. To give some overall comment first. Try to use tabs because it is really chaotic to read.
Also lose the buffer thing and stick to in / out or inout.
So I gues you want to reset the segs vector with the mr input and you want to be able to pause the thing with the pause input. One thing I do not understand is why you use both an enable and a pause input. Pause and enable is the same no, they only are logical inverse. Enable controls when you want the thing to run and pause controls when you want the thing to stop or pause. But bassically they both control the same running or not running, so I would call them redundant. Anyway the line if (pause = '0') then segs <= segs; is of no use in a clocked process.
In a clocked process you define the cases and conditions where you want the signals to change and if these are not so the signal keeps its value (its a register).

For the rest the code looks functionally OK.

So is the problem that your last counter doesn't wait for the previous one to first do a cycle?

For the second part of the code the erro I think is due to the fact that you write the following. I've tabbed for clarity.

elsif(clk'event and clk ='1') then
if (pause = '0') then
segs <= segs; -- again not needed
elsif(en = '0' and pause = '1') then
count <= count +1;
if (count ="1001") then -- Try elsif
count <= "0000";
else
count <= "0000";
end if;

You do not have priority encoding, I would try using elsif where you have the second if.

So this is what I advise if oyur thrying to make the following, a 3 digit counter whereby the next digit counts when there is an overflow in the previous.

entity segment_cnt is
port(
clk : in std_logic;
mr : in std_logic;
en : in std_logic;
segs : out std_logic_vector(6 downto 0);
clk_out : out std_logic;
rco : out std_logic
);
end segment_cnt


architecture RTL of segment_cnt is

signal temp : std_logic_vector(6 downto 0);

begin

cnt_procrocess(clk, mr)
begin
if(mr='0') then
temp <= "0000001";
elsif(clk'event and clk ='1') then
if(en = '0') then
case temp is
when "0000001" => -- 0 goto 1
temp <= "1001111";
when "1001111" => -- 1 goto 2
temp <= "0010010";
when "0010010" => -- 2 goto 3
temp <="0000110";
when "0000110"=> -- 3 goto 4
temp <="1001100";
when "1001100" => -- 4 goto 5
temp <="0100100";
when "0100100" => -- 5 goto 6
temp <="0100000";
when "0100000" => -- 6 goto 7
temp <="0001111";
when "0000111" => -- 7 goto 8
temp <="0000000";
when "0000000" => -- 8 goto 9
temp <="0001100";
when others => -- 9 goto 0
temp <="0000001";
end case;
end if;
end if;
end process cnt_proc;

clk_out <= clk;
rco <= '0'when (temp = "0001100" and en ='0')else '1';
segs <= temp;

end RTL;

So what this code above will do is :

If you make mr = 0 the counters will all go to the same value (mid segment iluminates I guess)

After this at every rising clock edge when the en = 0 the value of the counter (= temp signal) is checked and depending on the value of the temp signal the temp signal will go to the next value, so if en is continuously at zero the temp signal will keep cycling.

Whenever the temp signal is "0001100" and the en = 0 the rco flag will go low (1 clockcycle). This signal you can use to enable the counters in the other GALs.

So basically you load the code in the 3 GALS
for the first you connect the en I gues to something you can control test pin, jumper, switch, ...
The mr I guess is the same for all the GALS.
Then you need to connect the RCO of the first GAL to the en of the second and the RCO of the second to the en of the third. I also guess you use the clkout to route the clk to the next GAL?

Anyway I hope oyu understand what I mean give every counter a mr and a clk and cascade the enables via RCO1 to en2 and RCO2 to en3.
The en1 controls the complete 3 digit counter.

I hope this is what you were trying to build, if not please explain in more details what it is you want to do.

Keep in mind that organizing your code makes it more readable for both yourself and others and also remember to use priority encoding (= if elsif elseif else structure instead of separate ifs) and that clocked processes mean that if you do not specify a change to a signal or output it will keep its current value.

I hope I have helped you and I'm more than willing to help you out further if needed.

regards

jeandelfrigo
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top