I'm new to VHDL programming, and this is my first project - to build a binary counter with capability for both regular/reverse counting order. My plan is simple:
flag
.curr_s
in my code.ctl
signal as a sensitive, then switch curr_s
and reset the value of count
- which is set to store the counts of my last process.Now the thing is, however, that Quartus II returns me the error message:
Error (10028): Can't resolve multiple constant drivers for net "count[31]" at bi_counter.vhd(35)
Error (10029): Constant driver at bi_counter.vhd(46)
Error (10028): Can't resolve multiple constant drivers for net "count[30]" at bi_counter.vhd(35)
...
Error (10028): Can't resolve multiple constant drivers for net "count[14]" at bi_counter.vhd(35)
I googled a little bit and there are rules like it's not allowed to change the value of a signal
in multiple processes, but the problem is I declare my count
as a shared variable instead of signal - which should not encounter such error. And I intended to do this because I want to use count
as a variable to exchange information among processes - does this make sense and if not, is there any workaround?
Here is my code:
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
--
entity bi_counter is
port(
master_clk, ctl, rst: in std_logic;
q: out std_logic_vector(7 downto 0)
);
end bi_counter;
--
architecture behv of bi_counter is
shared variable curr_s: std_logic := '0'; -- 0 for incremental, 1 for reverse counting
shared variable count: integer := -1;
shared variable master_count: natural := 0;
signal flag: std_logic;
begin
p_freq_div: process(master_clk, rst)
begin
if rst = '0' then
master_count := 0;
elsif master_clk'event and master_clk='1' then
master_count := master_count + 1;
if master_count = 24000000 then
flag <= not flag;
master_count := 0;
end if;
end if;
end process p_freq_div;
p_count: process(flag)
begin
if curr_s = '1' then
count := count + 1;
q <= conv_std_logic_vector(count, 8);
else
count := count - 1;
q <= conv_std_logic_vector(count, 8);
end if;
end process p_count;
p_switch: process(ctl)
begin
if ctl'event and ctl='1' then
curr_s := not curr_s;
if curr_s = '0' then
count := 0;
else
count := 1000;
end if;
end if;
end process p_switch;
end behv;
You wrote:
I googled a little bit and there are rules like it's not allowed to change the value of a signal in multiple processes, but the problem is I declare my count as a shared variable instead of signal - which should not encounter such error.
This "rule" isn't just there to make your life more difficult.
Think about what you're trying to do. You're trying to synthesize something to put on your device that will hold a value, which you are trying to assign from two independent processes (even though they may be related and you know how they're supposed to work, they're still independent). No matter what linguistic element you use - signal, variable, whatever - it becomes irrelevant once you get to the device, which only has physical circuits. That is to say, you may not be violating any language rules, but you are violating a physical rule.
Your output can be stated in the following form: if some condition, then output something, else if some other condition, output something else, etc. And that can be put into a single process, which is what I suggest you do.
Also, as Russell suggested, you probably shouldn't use shared variables, especially to get around a language rule like you did.