Can't resolve multiple constant drivers for net - vhdl

I wrote this code. I want to count the numbers that I pressed they key_0 and if I press 2 times then the red led will turn on, how ever I get this error:
Can't resolve multiple constant drivers for net.
The thing is that I try to torn on 2 process at the same time how ever this tow process have the same variable: duty_cycle_counter.
What is the problem?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Pwm_control is
generic(display_resolution : INTEGER := 8);
port(
key_0 : in BIT;
green_led : out BIT;
red_led : out BIT
);
end Pwm_control;
architecture Behavioral of Pwm_control is
signal counter : std_logic_vector(display_resolution downto 0);
signal general_counter : std_logic_vector(23 downto 0); -- general_counter is for the clock divider , can get till 23
signal step_10_dc : STD_LOGIC_VECTOR(8 downto 0); --10 step PWM
signal step_5_dc : STD_LOGIC_VECTOR(8 downto 0); --5 step PWM
signal starting_value_0 : STD_LOGIC_VECTOR(8 downto 0); --0 step PWM
signal duty_cycle_counter : STD_LOGIC_VECTOR(8 downto 0);
begin
starting_value_0 <= "000000000";
step_5_dc <= "000011010";
step_10_dc <= "000110011";
duty_cycle_counter <= "000000000";
key_testing : process(key_0) --
begin
if (key_0 = '0') then
green_led <= '1';
duty_cycle_counter <= (duty_cycle_counter + step_5_dc);
else
green_led <= '0';
end if;
end process key_testing;
key_test_red_led : process(duty_cycle_counter)
begin
if (step_10_dc <= duty_cycle_counter) then
red_led <= '1';
end if;
end process key_test_red_led;
end Behavioral;

You're driving duty_cycle_counter continuously with 0 and trying to update it in the key_testing process. It looks like you wanted a start value (possible in most RAM-based FPGAs) or a reset, though in real life it will have some value so you could just leave out the initialization.

Related

VHDL-can't add numbers?

Hello I want to build a clock on my ALTERA DE2 that I can adjust the length of by pressing keys.
Now the problem is that when I convert from STD_LOGIC_VECTOR to UNSIGNED the code does not work:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all; Do not use with numeric_std
entity Adjust_Clock_4_buttens is
port(
clk,clk1 : in STD_LOGIC;
minutes_plus, minutes_minus,houres_plus,houres_minus : in STD_LOGIC;
minutes : IN STD_LOGIC_VECTOR(5 downto 0);
houres : IN STD_LOGIC_VECTOR(4 downto 0);
output_minutes : out STD_LOGIC_VECTOR(5 downto 0);
output_houres : out STD_LOGIC_VECTOR(4 downto 0);
LED_0 : OUT STD_LOGIC;
LED_1 : OUT STD_LOGIC;
LED_2 : OUT STD_LOGIC;
LED_3 : OUT STD_LOGIC
);
end entity Adjust_Clock_4_buttens ;
architecture behavioral of Adjust_Clock_4_buttens is
signal button1_r : std_logic_vector(2 downto 0);
signal button2_r : std_logic_vector(2 downto 0);
signal button3_r : std_logic_vector(2 downto 0);
signal button4_r : std_logic_vector(2 downto 0);
-- signal minutes_total : unsigned(5 downto 0) := (others => '0');
-- signal houres_total : unsigned(4 downto 0) := (others => '0');
signal minutes_total : unsigned(5 downto 0);
signal houres_total : unsigned(4 downto 0);
begin
process(clk)
begin
if (rising_edge(clk) )then
minutes_total<=unsigned(minutes);
houres_total<=unsigned(houres);
-- Shift the value of button in button_r
-- The LSB is unused and is there solely for metastability
button1_r <= button1_r(button1_r'left-1 downto 0) & minutes_plus;
button2_r <= button2_r(button2_r'left-1 downto 0) & minutes_minus;
button3_r <= button3_r(button3_r'left-1 downto 0) & houres_plus;
button4_r <= button4_r(button4_r'left-1 downto 0) & houres_minus;
if button1_r(button1_r'left downto button1_r'left-1) = "01" then -- Button1 rising --button1_r[2:1]
minutes_total <= (minutes_total + 1);
LED_0<='1';LED_1<='0';LED_2<='0';LED_3<='0';
elsif button2_r(button2_r'left downto button2_r'left-1) = "01" then -- Button2 rising --button1_r[2:1]
minutes_total <= (minutes_total-1 );
LED_0<='0';LED_1<='1';LED_2<='0';LED_3<='0';
end if;
if button3_r(button3_r'left downto button3_r'left-1) = "01" then -- Button1 rising --button1_r[2:1]
houres_total <= (houres_total + 1);
LED_0<='0';LED_1<='0';LED_2<='1';LED_3<='0';
elsif button4_r(button4_r'left downto button4_r'left-1) = "01" then -- Button2 rising --button1_r[2:1]
houres_total<= (houres_total-1 );
LED_0<='0';LED_1<='0';LED_2<='0';LED_3<='1';
end if;
end if;
end process;
output_minutes <= std_logic_vector(minutes_total);
output_houres <= std_logic_vector(houres_total);
end architecture behavioral ;
So in this code I get the time from another block the problem start when I try to add minutes and hours and for some reason it does not react to pressing of the keys. Could anyone explain maybe why is that?
The problem might be that you only have the clock in the sensitivity list of your process. Try adding the buttons in the sensitivity list, since they drive your if conditions. (Not sure if that's the problem but I guess it's worth a try)
minutes_total<=unsigned(minutes);
is on 2 lines, inside and outside of the process, which generates multiple line drivers, and will not work, ever!
(didn't read the rest of the code, there may be other problems, like hours not taking an e)
Now that it's inside the process, you need to rename minutes_total as minute_source, else you're incrementing the value only for the one clock cycle when you have a button edge!

How to transfer data from one process to another?

As an example, in the first process I have a binary number that I want to transfer to a second process. How to I do this?
Do i need to use something called a FIFO?
If I need to use a FIFO must I use it? Are there any alternatives?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity pwm_control_1 is
port (
--inputs and outputs for clock divider-------------------------------------------------------
clk_in : in std_logic ;
clr : in std_logic;
pwm_testing: out bit;
pwm_out: out bit;
key_0:in bit;
green_led:out bit
);
end pwm_control_1;
architecture Behavioral of pwm_control_1 is
signal compare:std_logic_vector( 8 downto 0);
signal q:std_logic_vector (8 downto 0);-- q is for the clock divider ,q can get till 23
signal q_1:std_logic_vector (23 downto 0);
signal pwm_testing_signal : bit;
signal test : std_logic_vector(8 downto 0);
signal step_10_dc : std_logic_vector(8 downto 0);
signal step_5_dc : std_logic_vector(8 downto 0);
signal duty_cycle_0 : std_logic_vector(8 downto 0);
signal duty_cycle_counter : std_logic_vector(8 downto 0);
signal duty_cycle_counter_refresh : std_logic_vector(8 downto 0);
begin
test <= "000000000";
step_10_dc <= "000110011";
step_5_dc <= "000011010";
duty_cycle_counter <= "000000000";
duty_cycle_counter_refresh <= "000000000";
--
key_testing :process (key_0)
begin
if (key_0='0') then
green_led <='1';
duty_cycle_counter <= (duty_cycle_counter+step_5_dc);-- counter for adding the limit of the PWM
else
green_led <='0';
end if;
end process key_testing;
` duty_cycle_counter_refresh <=duty_cycle_counter;
add_5_or_10_duty_cycle :process(clk_in,clr,q ,key_0)
begin
if (clk_in'event and clk_in='1') then -- starting the q counter
q<= q+1; --first I torn on the counter q that is used for clock driver then
if (q<=(duty_cycle_counter_refresh )) then pwm_testing_signal <='1';
else
pwm_testing_signal <='0';
end if ;
end if;
end process add_5_or_10_duty_cycle;
pwm_testing <=pwm_testing_signal;
end Behavioral;

VHDL - Index out range even If I made concurrent checking using when-else

I'm implementing a register file where I wanna read asynchronously and write on the rising edge.
I made concurrent checks on the addresses and the writing occurs inside a process.
However, it always cause me a fatal error and I don't know why!
Here's my code if anyone could help and tell me how can I read asynchronously and write on rising edge
Thank you!
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RegFile is
port(
outData1 : out std_logic_vector(15 downto 0);
outData2 : out std_logic_vector(15 downto 0);
inData : in std_logic_vector(15 downto 0);
writeEn : in std_logic;
reg1Sel : in std_logic_vector(2 downto 0);
reg2Sel : in std_logic_vector(2 downto 0);
writeRegSel : in std_logic_vector(2 downto 0);
clk : in std_logic
);
end RegFile;
architecture Register_File of RegFile is
type registerFile is array(0 to 5) of std_logic_vector(15 downto 0);
signal registers : registerFile;
signal reg1Address,reg2Address : integer;
signal reg1FinalAddressing,reg2FinalAddressing : std_logic_vector(2 downto 0);
begin
--Conversion of logic vector to unsigned integer
reg1Address <= to_integer(unsigned(reg1Sel));
reg2Address <= to_integer(unsigned(reg2Sel));
reg1FinalAddressing <= reg1Sel when (reg1Address<6 ) else
(others => '0');
reg2FinalAddressing <= reg2Sel when (reg2Address<6 ) else
(others => '0');
outData1 <= registers(to_integer(unsigned(reg1FinalAddressing)));
outData2 <= registers(to_integer(unsigned(reg2FinalAddressing)));
process (clk) is
begin
-- Reading from Registers 1 and 2
if rising_edge(clk) then
-- Writing to Register file Case Enabled
if writeEn = '1' then
registers(to_integer(unsigned(writeRegSel))) <= inData;
-- Case a value being written to register file, it will be out simultaneously if
-- the register was already selected. (The updated values are being released instantly).
if reg1Sel = writeRegSel then
outData1 <= inData;
end if;
if reg2Sel = writeRegSel then
outData2 <= inData;
end if;
end if;
end if;
end process;
end Register_File;

Pseudo Random Number Generator using LFSR in VHDL

I'm having a bit of trouble creating a prng using the lfsr method. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0);
begin
PROCESS(clock)
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN Qt <= "00000000";
ELSE Qt <= seed;
END IF;
temp <= Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
--Qt <= temp & Qt(7 downto 1);
END IF;
END PROCESS;
check <= temp;
Q <= Qt;
end Behavioral;
Here is the simulation I have ran:
prng sim
Firstly, the check output is just there so I can monitor the output of the temp signal. Secondly, the line that is commented out is what is causing the problem.
As can be seen from the simulation, on the first rising edge of the clock, the Qt signal reads the seed. However, and this is my question, for some reason the temp signal only XORs the bits of the Qt signal on the second rising edge of the clock. It remains undefined on the first clock pulse. Why is that? If it operated on the first rising edge right after the Qt signal reads the seed, then I could uncomment the line that shifts the bits and it would solve my problem. Any help would be much appreciated!
Here is the test bench if anyone cares:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1<='0'; wait for 50ns;
clock1<='1'; wait for 50ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1<='0'; wait for 900ns;
END PROCESS;
end bench;
I made some slight modifications to what you had (you are pretty much there though); I don't think the LFSR would step properly otherwise. I added an enable signal to the LFSR so you can effectively control when you want it to step. Resulting sim is here.
Just as a sidenote, you could also include a load and seed inputs if you wanted to seed the LFSR with a different value (instead of making it const).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
-- constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
--signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0) := x"01";
begin
PROCESS(clock)
variable tmp : STD_LOGIC := '0';
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN
-- credit to QuantumRipple for pointing out that this should not
-- be reset to all 0's, as you will enter an invalid state
Qt <= x"01";
--ELSE Qt <= seed;
ELSIF en = '1' THEN
tmp := Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
Qt <= tmp & Qt(7 downto 1);
END IF;
END IF;
END PROCESS;
-- check <= temp;
check <= Qt(7);
Q <= Qt;
end Behavioral;
And tb:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
signal en : STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
en => en,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1 <= '0'; wait for 50 ns;
clock1 <= '1'; wait for 50 ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1 <= '0';
en <= '1';
wait for 900 ns;
END PROCESS;
end bench;

ModelSim - Unable To Simulate Button Presses

I want to use four push buttons as inputs and three seven-segment LED displays as outputs. Two push buttons should step up and down through the sixteen RAM locations; the other two should increment and decrement the contents of the currently-displayed memory location. I have the following two entities:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DE2_TOP is
port (
KEY : in std_logic_vector(3 downto 0); -- Push button
CLOCK_50: in std_logic;
);
end DE2_TOP;
architecture datapath of DE2_TOP is
begin
U1: entity work.lab1 port map (
key => key,
clock => clock_50,
);
end datapath;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity raminfr is -STANDARD RAM INFERENCE
port (
clock: in std_logic;
we : in std_logic;
a : in unsigned(3 downto 0);
di : in unsigned(7 downto 0);
do : out unsigned(7 downto 0)
);
end raminfr;
architecture rtl of raminfr is
type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
signal read_a : unsigned(3 downto 0);
begin
process (clock)
begin
if rising_edge(clock) then
if we = '1' then
RAM(to_integer(a)) <= di;
end if;
read_a <= a;
end if;
end process;
do <= RAM(to_integer(read_a));
end rtl;
and
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lab1 is
port(
clock : in std_logic;
key : in std_logic_vector(3 downto 0);
);
end lab1;
architecture up_and_down of lab1 is
signal value_in_ram : unsigned(7 downto 0);
signal we : std_logic;
signal value_counter : unsigned(7 downto 0) ;
signal register_counter : unsigned(3 downto 0);
begin
U1: entity work.raminfr port map (
a => register_counter,
di => value_counter,
do => value_in_ram,
clock => clock,
we => we
);
process(clock)
begin
if rising_edge(clock) then
if (key(3)='0' and key(2)='0' and key(1)='1' and key(0)='0') then
value_counter <= value_counter + "1";
elsif (key(3)='0' and key(2)='0' and key(1)='0' and key(0)='1') then
value_counter <= value_counter - "1";
elsif (key(3)='1' and key(2)='0' and key(1)='0' and key(0)='0') then
register_counter<= register_counter + "1";
value_counter <= value_in_ram;
elsif (key(3)='0' and key(2)='1' and key(1)='0' and key(0)='0') then
register_counter<= register_counter - "1";
value_counter <= value_in_ram;
end if;
end if;
end process;
end architecture up_and_down;
I also have the following test bench, where I try to simulate buttons being pressed via KEY:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DE2_TOP_TEST is
end;
architecture BENCH of DE2_TOP_TEST is
signal KEY : std_logic_vector(3 downto 0);
signal CLOCK_50 : std_logic := '0';
signal hex4, hex5, hex6 : std_logic_vector(6 downto 0);
begin
clock_50 <= not clock_50 after 50 ns;
process
begin
KEY<="0010";
wait for 1 us;
KEY<="0000";
end process;
uut:work.DE2_TOP port map (
KEY=>key,
CLOCK_50=>clock_50,
hex4=>hex4,
hex5=>hex5,
hex6=>hex6
);
end BENCH;
My test bench set up looks like this:
To simulate, I compile all three of the above files, and then simulate DE2_TOP_TEST, but am met with the result that my "KEY" is still undefined, as below (although CLOCK_50 does get the default value that I set):
Anyone know what's causing this?
(1) You have unconnected ports on the entity you are typing to test. The test results are as expected for those inputs - specifically, clk, being undriven.
(2) Having connected clk, you will need to drive it.
signal clk : std_logic := '0';
and
clk <= not clk after 50 ns;
should give a 10MHz clock, check this in the simulator
(3) Drive "KEY" with a specific sequence of values
subtype keys is std_logic_vector(3 downto 0);
constant count_up : keys := "0001";
constant count_dn : keys := "0010";
constant idle : keys := "0000";
-- etc
process
begin
KEY <= count_up;
wait for 1 us;
KEY <= idle;
wait for ...
-- etc
end process;
(4) Bring the OUTPUTS back out into the testbench so that you can check their values. You need to bring them out as ports in the top level (design) entity anyway, if you are going to connect them to a display!
Then (later, once things have started going to plan) you can test them in the testbench process...
wait for 100 ns;
-- after the last press, we should have "07" on the display
assert digit(1) = "0111111" report "Left digit has wrong value" severity ERROR;
assert digit(0) = "0000111" report "Left digit has wrong value" severity ERROR;
A self-checking testbench like this saves debugging by staring at waveforms. You only need the waveforms when the tests are failing...

Resources