Hi,
there is a problem with VHDL. My project (see below) is very simple and
has two inputs: "rx_clock" (low frequency) and "clk" (high frequency).
It is necessary to increment signal "counter" by every "clk" pulse. If
positive edge of "rx_clock" appears the "counter" must be zeroed (only
with edge of "rx_clock" !).
I want to do it without FSM (because it is clear with FSM), but only
with PROCESSes and concurrent code.
Implementation of this problem is blocked by using of shared variable
(or signal) which must be drived in different parts of code. And this
results in error: can't resolve multiple constant drivers for net
"flag".
Please, explain the possible solution of such problem.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY prb IS
PORT( rx_clock: IN STD_LOGIC;
clk: IN STD_LOGIC;
outp: OUT STD_LOGIC);
END prb;
ARCHITECTURE arch OF prb IS
SIGNAL counter: UNSIGNED (7 DOWNTO 0);
SHARED VARIABLE flag: STD_LOGIC := '0';
BEGIN
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk='1') THEN
counter <= counter + 1;
IF(flag = '1') THEN
flag := '0';
counter <= X"00";
END IF;
END IF;
END PROCESS;
PROCESS(rx_clock)
BEGIN
IF(rx_clock'EVENT AND rx_clock = '1') THEN
flag := '1';
END IF;
END PROCESS;
outp <= flag;
END arch;

You try to assign a value to the flag out of two (clocked) processes.
Thats not possible, because flag is a flipflop in hard real life. And
you try to describe a FF with two clock inputs: clk and RX_clk.
What you need is a "usual" edge detection like that:
[vhdl]
ARCHITECTURE arch OF prb IS
SIGNAL counter: UNSIGNED (7 DOWNTO 0);
signal flag: STD_LOGIC := '0';
BEGIN
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk='1') THEN
counter <= counter + 1;
IF(flag = '1') THEN
flag <= '0';
counter <= X"00";
END IF;
IF(rx_clock_old = '0' AND rx_clock = '1') THEN -- edge detection
flag <= '1';
END IF;
rx_clock_old <= rx_clock;
END IF;
END PROCESS;
outp <= flag;
[vhdl]
BTW:
If you are starting with VHDL now, you will not need variables the next
12 weeks. And especially not a shared variable. Instead you should use
signals.

Na sowas,
Thank you very much!
It is very pleasant to get quick and useful reply from guru.
You opened my eyes, indeed.
8-)
If you don't make an objection I would discuss about problem of complex
VHDL code. As I dealed with C/C++ before VHDL, it is rather difficult to
change my mind. I suppose that it is very uncomfortable to program
without possibility of changing signals/variables in different parts of
code.
Is it appropriate intention that we are strictly limited by potential
complexity of algorithm in VHDL?

> Is it appropriate intention that we are strictly limited by potential> complexity of algorithm in VHDL?
You must keep in mind that the synthesizer must be able to transform
your VHDL description (it is NOT an VHDL program!!!) into flipflops and
combinatorial logik.
The synthesizers are getting better each day, but they are far away from
be able to tanslate anything you can write down in C. After having
programmed C
you must learn a new way of THINKING.
> I suppose that it is very uncomfortable to program without possibility> of changing signals/variables in different parts of code.
As I said: you are not programming. You are trying to describe hardware.
Also in C it is not possible to access a variable the same time! In C
the writing works because the access is one after the other. But in VHDL
a storage element (flipflop) has only 1 input and 1 clock, so there must
be implemented some logik to share these ressources. And if thats not
possible, the synthesizer says: multiple drivers (at the same time on
that one component).
VHDL is a language to describe and verify SYSTEMS. Just a very small
portion of it is synthesizable. See this little piece of code:

output <= input after1 ms;

Everyone is able to sse, what should happen. The simulator will make it
happen. But the synthesizer is not able to make real hardware out of it
:-/