Forum Discussion
Altera_Forum
Honored Contributor
15 years agolet me go through the code, bit by bit. You have other problems other than what you're asking about:
port
(
pin_clk: in std_logic; -- our input clock
pin_button1: in std_logic; -- user button, fires a signal1
pin_led_output: buffer std_logic; -- user sees that a button has been pushed
pin_ir_output: buffer std_logic -- IR output signal
);
end keyfob_top;
Buffers are not the prefered option of doing things in VHDL now, most people prefer to use an internal signal and assign that to an output. But, I leave it up to you.
-- apply the correct value to button1 (which is a signal)
procedure set_button1(constant status : std_logic) is
variable tmp : std_logic;
begin
if status = button_up then
tmp := button_up; -- has just been pressed
else
tmp := button_down; -- has just been released
end if;
button1 <= tmp;
end procedure set_button1;
Two things. 1. why dont you do this instead? On real hardware, "status" can only be '0' or '1'. button1 <= status; 2. Its generally not a good idea to assign a signal thats not in the scope of the procedure. You can do it, but I suspect you'll be getting yourself into trouble, like you already have. Usually, its better to create a signal output on the procedure and connect the signal to that.
procedure set_button1(constant status : std_logic; signal output : out std_logic) is
begin
output <= status;
end procedure set_button1;
.... then call it:
set_button1(status => input, output => button1);
-- triggered when pin_button1 has been pressed
trigger_button1: process
begin
wait until pin_button1 = '1'; -- wait until pin_button1 is pressed
set_button1(button_down); -- pin_button1 has just been pressed.
button1_bits_left <= 8;
end process trigger_button1;
Again, using waits is not the prefered method of clocking logic. You are also using logic as a clock, which is highly inadvisable.
-- do we have anything to send out
data_out: process
begin
wait until baud_tick = '1'; -- line 65 -- wait on rising edge
-- does button1 need to be serviced
if button1 = button_down then
....
set_button1(button_up); -- reset our button
pin_led_output <= led_off; -- show user what is going on
......
end process data_out;
There is your problem. You already assigned button1 in the "trigger_button1" process. Signals can only be assigned from a single process, otherwise you get multple driver error like you did. Its because "trigger_button1" is always driving "button_down" onto the signal, while "data_out" always drives "button_up". So they are in conflict.