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.

problem with instantiation in VHDL

Status
Not open for further replies.

rg350dxlover

Member level 1
Joined
Jul 15, 2008
Messages
35
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Malaysia
Activity points
1,566
Hi...
So, basically if the input is = 1000, then it's equal. otherwise not equal. I'm having trouble with some instantiation here. Can't figure out what it is. I hope you guys can help me with this. Thanks!
Here is my game_counter code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity game_counter is
port( RST, CLK: in std_logic;
COUNT_NUM: out unsigned(3 downto 0));
end game_counter;

architecture arch of game_counter is
signal COUNT: unsigned(3 downto 0);
begin
process (CLK, RST)
begin
if RST = '0' THEN
COUNT <= (others => '0');
elsif rising_edge(CLK) then
if COUNT < 9 then
COUNT <= COUNT + 1;
else
COUNT <= (others => '0');
end if;
end if;
end process;

COUNT_NUM <= COUNT;
end arch;

Here's my comparator code:

--libraries to be used are specified here
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

--entity declaration with port definitions
entity compare is
port( inCLK, inRST : in std_logic_vector(3 downto 0);
equal, unequal : out std_logic_vector(3 downto 0));
end compare;

architecture Behavioral of compare is
component game_counter
port(RST, CLK: in std_logic_vector(3 downto 0);
COUNT_NUM: out unsigned(3 downto 0));
end component;

for all: game_counter use entity work.game_counter(arch);

signal X: std_logic_vector(3 downto 0);

begin
gc0: game_counter port map (inCLK, inRST, COUNT_NUM);
process(COUNT_NUM)
begin
if (COUNT_NUM = "1000") then
equal <= '1';
unequal <= '0';
else
equal <= '0';
unequal <= '1';
end if;
COUNT_NUM <= X;
end process;
end Behavioral;
 

several problems here:

use ieee.std_logic_arith.all;

Dont use this package, it is non-standard. Use numeric_std isntead:

ieee.numeric_std.all;

2. In the comparator:

--libraries to be used are specified here
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

You need to add the numeric_std library to see the unsigned type.


3.
Code:
signal X: std_logic_vector(3 downto 0);

begin
gc0: game_counter port map (inCLK, inRST, COUNT_NUM);
process(COUNT_NUM)
begin
	if (COUNT_NUM = "1000") then
		equal <= '1';
		unequal <= '0';
	else
		equal <= '0';
		unequal <= '1';
	end if;
			
	COUNT_NUM <= X;
end process;

You have not decalred a COUNT_NUM signal.

4. You cant assign anything to count_num, you've already connected it to the output of your game_count (you'll get a dual driver problem, and get X's)

This is the start. Have another go and see what happens
 
You didn't report a particular error message, but there are in fact several faults.

inCLK, inRST : in std_logic_vector(3 downto 0); should be std_logic
RST, CLK: in std_logic_vector(3 downto 0); should be std_logic
COUNT_NUM undefined in entity compare
COUNT_NUM <= X; COUNT_NUM is continuously assigned in the instantiation of game_counter
 
Thanks TrickyDicky and FvM. So I did some editing based on your comments and got confused along the way. But there's still error. Something wrong with the operator for
--> if (inCLK = "1000") then ....
Here's the edited version.
-------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity compare is
port( inCLK, inRST : in std_logic;
Q, equal, unequal: out unsigned(3 downto 0));
end compare;

architecture Behavioral of compare is
component game_counter
port(CLK, RST: in std_logic;
COUNT_NUM: out unsigned(3 downto 0));
end component;

for all: game_counter use entity work.game_counter(arch);

signal X: unsigned(3 downto 0);
begin
gc0: game_counter port map (inCLK, inRST, X);
process(X)
begin
if (inCLK = "1000") then
X <= EQUAL;
else
X <= UNEQUAL;
end if;
end process;
Q <= X;
end Behavioral;
 

you cant assign anything to X, because its already connected to the game_counter component. Even worse, you cannot assign X from outputs.

if inCLK = "1000" then

inCLK is a single bit so you cant compare it to an array. Why do you want to compare the inclock to a number anyway? I think you mean:

if X = "1000" then

or even better

if X = 8 then

Here is the code I think you meant:

Code:
process(inCLK)
begin
  if rising_edge(inCLK) then
    if X = 8 then
      EQUAL <= X;
    else
      UNEQUAL <= X;
    end if;
  end if;
end process;
 
OMG big thanks. That's exactly what I meant. What was I thinking? Sorry I think I just need more practice with this.
Anyway, I'm not sure if what I'm doing is right or wrong. But basically, I'm supposed to design a game where it counts up from 0 to 9. If user catches input 8 then the counter will go to the next level (frequency divider is still in progress), otherwise it will stay at the current level. Will the code work for this system?
 

how are you producing a frequency divider? you should not create a clock - you should keep the clock constant and generate clock enables at different rates (there are timing problems when you create your own clocks).

Keep going with what you're doing. Come back here if you need more help.
 

Thanks for the guidelines. But how do I keep the clock constant and generate clock enables at different rates? for this counter I have to generate from 1 Hz to 10 Hz with increment of 1 Hz for each level.
 

the standard clock enable template is this:

Code:
process(clk)
begin
  if rising_edge(clk) then
    if enable = '1' then
      --do something
    end if;
  end if;
end process;

Then elsewhere, instead of creating a toggling clock, just create an enable that lasts for 1 clock cycle. for example, if you're using the high bit on a counter (as most people do when creating a frequency divider), all you need to do is see when the counter is a specific value
Code:
process(clk)
begin
  if rising_edge(clk) then
    count <= count + 1;

    if count = 77 then --just detect 1 value, doesnt really matter what

      enable <= '1'; --only high for 1 clock cycle and low for 2^n-1 clocks (where n is the width of the counter)
    else
      enable <= '0';
    end if;
  end if;
end process;


---------- Post added at 22:46 ---------- Previous post was at 22:41 ----------

if you want enable to be a specific width, you can just detect when the counter is between two values.
You can run 1 counter and use several bits extracted from it for different speed enables:

if (count rem 256) = 0 then --high for 1, low for 255
if (count rem 16) = 0 then --high for 1, low for 15

etc
The remainder function for ( count rem 2^n) is free in logic, because it just ignored the MSBs
 
Hi again... I'm stuck. I can't figure out how to fix it but there's error saying --> can't determine the definition for operator "+" and the error is with this line --> X <= level + 1
Here's the modified code. Hope you can help me with this.


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

entity frequency_divider is
port( divCLK: in std_logic;
level: in std_logic;
CLK_out: out std_logic);
end frequency_divider;

architecture behavior of frequency_divider is
signal X: std_logic;
begin
process(divCLK, level)
variable count : integer range 0 to 77;
begin
if rising_edge(divCLK) then
if (count rem 16) = 0 then --high for 1, low for 15
count := count + 1;
if count = 8 then
CLK_out <= '1';
X <= level + 1;
else
CLK_out <= '0';
X <= level;
end if;
end if;
end if;
end process;
end behavior;
 

Hey, the problem is that level is of type STD_LOGIC, the '+'- operator can only be used with integers and signed/unsigned.

Besides that, VHDL is a strongly typed language, wich implies that: output <= input. level(of direction IN) can NEVER be on the left side of the '<=' -sign.
If you want something like that, you'd have to use a signal(wich is in fact a bus, it has no direction).
 
Thanks 153rd. I already fixed that. But I have other errors. again. =/
Thanks in advance.


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

entity frequency_divider is
port( divCLK: in std_logic;
level: in unsigned(3 downto 0);
CLK_out: out std_logic);
end frequency_divider;

architecture behavior of frequency_divider is
signal X: unsigned(3 downto 0);
begin
process(divCLK, level)
variable count : integer range 0 to 9;
begin
if rising_edge(divCLK) then
if (count rem 16) = 0 then --high for 1, low for 15
count := count + 1;
if count < 9 then
X <= level + 1;
else
X <= level;
end if;
end if;
end if;
end process;
with level select
CLK_out <= divCLK when "1000",
not divCLK when others;
end behavior;
 

But I have other errors. again.
You missed to tell about it.

The remainder 16 operation seems pretty useless for a range 0 to 9 integer. Nevertheless it prevents count from exceeding a value of 1. Is this what you want?
Code:
if (count rem 16) = 0 then --high for 1, low for 15
  count := count + 1;
  if count < 9 then
    X <= level + 1;
  else
    X <= level;
  end if;
end if;
 

Thank FvM.

The remainder 16 operation seems pretty useless for a range 0 to 9 integer. Nevertheless it prevents count from exceeding a value of 1. Is this what you want?
Code:
No, that is not what I want. I mean I don't want to prevent count from exceeding a value of 1.
Anyway, did some discussion with a friend and we got this.

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

entity frequency is
port(CLK, sel: in std_logic;
clkdiv: in unsigned;
q: out std_logic);
end frequency;

architecture arch of frequency is
signal temp: unsigned;
signal CLK1Hz, CLK2Hz, CLK3Hz, CLK4Hz, CLK5Hz, CLK6Hz, CLK7Hz, CLK8Hz, CLK9Hz, CLK10Hz: unsigned;
begin
process(CLK)
begin
if rising_edge(CLK) then
temp <= clkdiv + 1;
end if;
end process;
-- F=0.9934Hz, T=1.0066s,
CLK1Hz <= clkdiv(24);
CLK2Hz <= clkdiv(23);
CLK3Hz <= clkdiv(23) + clkdiv(24);
CLK4Hz <= clkdiv(22);
CLK5Hz <= clkdiv(22) + clkdiv(24);
CLK6Hz <= clkdiv(22) + clkdiv(23);
CLK7Hz <= clkdiv(21) + clkdiv(24);
CLK8Hz <= clkdiv(21);
CLK9Hz <= clkdiv(21) + clkdiv(24);
CLK10Hz <= clkdiv(21) + clkdiv(23);

process(CLK1Hz,CLK2Hz,CLK3Hz,CLK4Hz,CLK5Hz,CLK6Hz,CLK7Hz,CLK8Hz,CLK9Hz,CLK10Hz,sel)
begin
case sel is
when "0000" => q<=CLK1Hz;
when "0001" => q<=CLK2Hz;
when "0010" => q<=CLK3Hz;
when "0011" => q<=CLK4Hz;
when "0100" => q<=CLK5Hz;
when "0101" => q<=CLK6Hz;
when "0110" => q<=CLK7Hz;
when "0111" => q<=CLK8Hz;
when "1000" => q<=CLK9Hz;
when "1001" => q<=CLK10Hz;
when others => q<=CLK1Hz;
end case;
end process;
end arch;

However, there's an error saying "indexed name returns a value whose type does not match unsigned"
 

several problems here.
First: Temp has no bounds - neither have all your clock signals.
Second: clkdiv(n) is a std_logic, not an unsigned!
Third: You're doing exactly what I told you NOT to do - you're generating a load of clocks rather than generating a load of enables. THis is a BAD THING (you can cause all sorts of timing problems with larger designs, you might get away with it on a smaller design, but its bad practice!)
 
I'm sorry (vhdl is a bit complicated in my head) but I don't get what you meant:
you're generating a load of clocks rather than generating a load of enables.
Hope you can explain this.

Also, what does it mean by having constant drivers?
Thanks!
 

What he means is that a design should always have ONE clock 'line' ONLY. What you're doing with all those signals, is generating like 10 different clock lines, and then connecting them to one output.
This will create timing problems later one, when you have a bunch of components running on a bunch of different clocks

You have to make 10 outputs, and each one of them get a value after a certain amount of time:
when "0000" => outp1HZ<='1';
when "0001" => outp2Hz<='1';outp1Hz <= '0';
etc etc.
 
Thanks 153rd. I think I get a clearer picture now.

But what does the error "can't resolve multiple constant drivers mean"?
 

But what does the error "can't resolve multiple constant drivers mean"?
Apparently, there's no multiple driver issue in the posted code.

The error means, you are ignoring the VHDL rule, that a signal can be only assigned in one place in concurrent code respectively only one process. It's typically revealing confusion about the overall code structure.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top