10028 Can't solve multiple constant drivers for net "D[x]" - vhdl

Hi pleople this is my code, and the only error is Error (10028): Can't resolve multiple constant drivers for net "D[22]" at bonus2.vhd(26). I<m new at this and I don't understant this error.
Here is my code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bonus2 is
port (
B,C : in unsigned(15 downto 0);
clear, clk : in std_logic;
Q : out unsigned(31 downto 0)
);
end entity bonus2;
architecture arch_bonus2 of bonus2 is
signal mult : unsigned(31 downto 0); --signal d'addition
signal D: unsigned(31 downto 0); --signal d'addition
begin
mult <= B * C;
process(clear)
begin
if clear = '1' then
D <= x"00000000";
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
D <= mult + D;
end if;
end process;
Q <= D;
end architecture arch_bonus2;

Your code shows that you might be unfamiliar with some concepts of hardware design, so I suggest you catch up on combinational/sequential logic and how to describe them with VHDL. Also, a good rule of thumb is that you should be able to draw some parts of your design, and if you do you'll see that the D wire is driven by multiple nets.
What I believe you want to do, based on your code, is to be able to reset/initialize your output register. However, the way you have coded it suggests you want an asynchronous reset.
Please check here to know more about synch vs asynch logic and then I suggest you to explore further to understand the implications.
Here is a modified version of your code with an asynchronous reset, because it seems what you want.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bonus2 is
port (
B,C : in unsigned(15 downto 0);
clear, clk : in std_logic;
Q : out unsigned(31 downto 0)
);
end entity bonus2;
architecture arch_bonus2 of bonus2 is
signal mult : unsigned(31 downto 0); --signal d'addition
signal D: unsigned(31 downto 0); --signal d'addition
begin
mult <= B * C;
process(clk,clear)
if clear == '1' then
D <= x"00000000";
elsif rising_edge(clk) then
D <= mult + D;
end if;
end process;
Q <= D;
end architecture arch_bonus2;

Related

Error (10448): VHDL error at teste.vhd(33): record type std_ulogic is used but not declared

I was trying to do a work and this error is boring me, i pass to a new project teste.vhdl and this keep happening, i need to have two barriers of clock one for input and another to output, to use timequest with combinational logic.
The 'and' is just a example.
library ieee;
use ieee.std_logic_1164.all;
--use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
ENTITY teste IS
PORT(
clock : in std_logic;
clear : in std_logic;
a : in std_logic_vector(3 downto 0);
b : in std_logic_vector(3 downto 0);
s : out std_logic_vector(3 downto 0)
);
END teste;
ARCHITECTURE comportamento OF teste IS
signal a1,b1,s1 : std_logic_vector(3 downto 0);
begin
FF_in: process(clock.clear)
begin
if clear = '1' then
a1 <= "0000";
b1 <= "0000";
elsif clock'event and clock = '1' then
a1 <= a;
b1 <= b;
end if;
end process;
s1 <= a1 and b1;
FF_out: process(clock.clear)
begin
if clear = '1' then
s <= "0000";
elsif clock'event and clock = '1' then
s <= s1;
end if;
end process;
END comportamento;
You have used a . Rather than , in the process sensitivity list. Using a . Is trying to access a record field.

4-bit comparator issue in vhdl

I am new to VHDL and I have an issue writing a 4-bit comparator.
When I want to compare different sets of inputs there is only one output for all of them. And I don't know how to solve this problem. I want to have only one output and need to show 0000 if A is less than B, and 1111 if A is greater than B, and 0011 if they are equal. Can anybody please help me with my problem?
Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity comp_4 is
port ( A:IN STD_LOGIC_VECTOR(3 downto 0);
B:IN STD_LOGIC_VECTOR(3 downto 0);
output:OUT STD_LOGIC_VECTOR(3 downto 0)
);
end comp_4;
architecture dataflow of comp_4 is
begin
process
begin
if (A=B) then
output <= "0011";
elsif (A>B) then
output <= "1111";
else
output <= "0000";
end if;
wait;
end process;
end dataflow;
And also my test bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Comparator_test IS
END Comparator_test;
ARCHITECTURE Ctest OF Comparator_test IS
COMPONENT comp_4 IS
port( A:IN STD_LOGIC_VECTOR(3 downto 0);
B:IN STD_LOGIC_VECTOR(3 downto 0);
output:OUT STD_LOGIC_VECTOR(3 downto 0)
);
END COMPONENT;
SIGNAL a : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL b : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL c : STD_LOGIC_VECTOR(3 downto 0);
BEGIN
uut : comp_4 PORT MAP(a, b , c);
a <= "0100" , "1111" After 10 NS;
b <= "0101" , "1100" AFTER 10 NS;
END Ctest;
And my simulation looks like this:
You need to put the inputs on the sensitivity list.
Note, wait; stops the process infinitely (only in simulation, it cannot be synthesized).
Solution 1:
Use the process' sensitivity list, and remove wait;.
architecture dataflow of comp_4 is
begin
process(A, B)
begin
if (A = B) then
output <= "0011";
elsif (A > B) then
output <= "1111";
else
output <= "0000";
end if;
end process;
end dataflow;
Solution 2:
Use the sensitivity list of wait.
architecture dataflow of comp_4 is
begin
process
begin
if (A = B) then
output <= "0011";
elsif (A > B) then
output <= "1111";
else
output <= "0000";
end if;
wait on A, B;
end process;
end dataflow;

Initial value of unsigned in VHDL

I am using Altera Max plus II, writing in VHDL.
In the architecture I am given this command:
signal count_value : unsigned (3 downto 0);
I noticed that the initial value of count_value is 0000.
How can I change it?
EDIT:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all ;
entity decade_counter is
port ( clk : in std_logic;
q : out unsigned(3 downto 0) );
end entity decade_counter;
architecture rtl of decade_counter is
signal count_value : unsigned(3 downto 0);
begin
count : process (clk) is
begin
if rising_edge(clk) then
if count_value = 9 then
count_value <= "0000";
else
count_value <= count_value + 1;
end if;
end if;
end process count;
q <= count_value;
end architecture rtl;
I have this code which is a BCD Counter from 1 to 9. I want to modify it so that it goes from 7 to 12. That's the reason why I want count_value to initialize at 0111.
Thanks in advance
First - don't use std_logic_arith. It is not part of the standard, and often generates problems. Use numeric_std instead.
Second - initialization. You can do it in two ways:
Init value at declaration of the signal. This is possible, but you must check if your device support it. If you want your code to be portable, use second method.
Reset. Preferably synchronous, as it is usually part of the logic.
Example (haven't checked it, but should work):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all ;
entity decade_counter is
port (
clk : in std_logic;
reset_n: in std_logic;
q : out std_logic_vector(3 downto 0)
);
end entity decade_counter;
architecture rtl of decade_counter is
signal count_value : unsigned(3 downto 0);
-- Possibly:
-- signal count_value : unsigned(3 downto 0) := "0111";
begin
count : process (clk) is
begin
if rising_edge(clk) then
if resetn = '0' then
count_value <= "0111";
else
if count_value >= 12 then
count_value <= "0111";
else
count_value <= count_value + 1;
end if;
end if;
end if;
end process count;
q <= std_logic_vector(count_value);
end architecture rtl;
If it be that you want to provide some value to it at build time.I suggest you try this method
signal count_value : unsigned (3 downto 0) := "xxxx";
This "xxxx" could be any std_logic_Vector value you want
Hope it helps!

Implementing Overflow Checking in 4-bit Adder/Subtractor (VHDL)

I am rather new (3 weeks) to VHDL, and I am having a problem in my latest assignment, which involves implementing overflow checking in a simple 4-bit adder:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity add_sub_4bit is
Port ( a : in STD_LOGIC_VECTOR(3 downto 0);
b : inout STD_LOGIC_VECTOR(3 downto 0);
sel: in STD_LOGIC );
--sum : inout STD_LOGIC_VECTOR(3 downto 0)
end add_sub_4bit;
architecture Behavioral of add_sub_4bit is
signal localflow : STD_LOGIC;
signal localsum : STD_LOGIC_VECTOR (3 downto 0);
begin
localsum <= a + b when sel = '1'
else
a - b;
process(a,b,localsum) begin
if a(3) = '0' AND b(3) = '0' AND localsum(3) = '1' then
localflow <= '1';
elsif a(3) = '1' AND b(3) = '1' AND localsum(3) = '0' then
localflow <='1';
else
localflow <='0';
end if;
end process;
end Behavioral;
Now, the test cases are as such:
A=5, B=-3, giving 0 to sel adds them, 1 subtracts.
A=6, B=2, working much the same.
Now, given that the numbers are signed, of course, they are two's complement numbers, so is the result. However, I can only detect overflow in a case of adding 6 (0110) and 2 (0010), giving out -8 (1000), which is obviously an overflow case in 4-bit. But, when doing 5 -(-3), the result is much the same, 1000, but since I have given numbers of two different signs, I cannot detect overflow using my method.
My teacher has suggested that we change the sign of B depending on the value of sel - I tried something like making b <= b+"1000" based on that but that didn't help, and I don't know of other ways, being very new to the language. What can I do to get a proper program? Thank you.
Firstly:
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Don't do that. Especially if you want the numbers to be signed. Normal to use is:
use IEEE.numeric_std.all;
After that, you should cast the std_logic_vector to the wanted data type, e.g. 'signed', for the correct arithmetic.
Secondly, don't use inout. VHDL is not so good with bidirectional assignments. Either use in or out.
So combining the above, you could do (n.b. not the best code):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity add_sub_4bit is
Port (
a : in STD_LOGIC_VECTOR(3 downto 0);
b : in STD_LOGIC_VECTOR(3 downto 0);
sel: in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(3 downto 0);
overflow : out std_logic
);
end add_sub_4bit;
architecture Behavioral of add_sub_4bit is
signal localflow : STD_LOGIC;
signal locala, localb, localsum : signed(4 downto 0); -- one bit more then input
signal sumout : std_logic_vector(4 downto 0);
begin
locala <= resize(signed(a), 5);
localb <= resize(signed(b), 5);
localsum <= locala + localb when sel = '1' else locala - localb;
-- overflow occurs when bit 3 is not equal to the sign bit(4)
localflow <= '1' when localsum(3) /= localsum(4) else '0';
-- convert outputs
sumout <= std_logic_vector(localsum);
--outputs
sum <= sumout(4)&sumout(2 downto 0);
overflow <= localflow;
end Behavioral;
You can test this using a testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity add_sub_4bit_tb is
end add_sub_4bit_tb;
architecture Behavioral of add_sub_4bit_tb is
signal sel : std_logic_vector(0 downto 0);
signal a, b, sum : std_logic_vector(3 downto 0);
begin
uut: entity work.add_sub_4bit
port map (a, b, sel(0), sum);
test: process
begin
for sel_o in 0 to 1 loop
sel <= std_logic_vector(to_signed(sel_o, 1));
for a_o in -8 to 7 loop
a <= std_logic_vector(to_signed(a_o, 4));
for b_o in -8 to 7 loop
b <= std_logic_vector(to_signed(b_o, 4));
wait for 1 ns;
end loop;
end loop;
end loop;
wait;
end process;
end Behavioral;

Can anyone help me with this VHDL code (currently malfunctioning)?

This code should be (and is) very simple, and I don't know what I am doing wrong.
Here is description of what it should do:
It should display a number on one 7-segment display. That number should be increased by one every time someone presses the push button. There is also reset button which sets the number to 0. That's it. Here is VHDL code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PWM is
Port ( cp_in : in STD_LOGIC;
inc : in STD_LOGIC;
rst: in std_logic;
AN : out STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0));
end PWM;
architecture Behavioral of PWM is
signal cp: std_logic;
signal CurrentPWMState: integer range 0 to 10;
signal inco: std_logic;
signal temp: std_logic_vector (3 downto 0);
begin
--cp = 100 Hz
counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
debounce: entity debounce port map (inc, cp, inco);
temp <= conv_std_logic_vector(CurrentPWMState, 4);
ss: entity decoder7seg port map (temp, segments);
process (inco, rst)
begin
if inco = '1' then
CurrentPWMState <= CurrentPWMState + 1;
elsif rst='1' then
CurrentPWMState <= 0;
end if;
end process;
AN <= "1110";
end Behavioral;
Entity djelitelj (the counter used to divide 50MHz clock):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PWM is
Port ( cp_in : in STD_LOGIC;
inc : in STD_LOGIC;
rst: in std_logic;
AN : out STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0));
end PWM;
architecture Behavioral of PWM is
signal cp: std_logic;
signal CurrentPWMState: integer range 0 to 10;
signal inco: std_logic;
signal temp: std_logic_vector (3 downto 0);
begin
--cp = 100 Hz
counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
debounce: entity debounce port map (inc, cp, inco);
temp <= conv_std_logic_vector(CurrentPWMState, 4);
ss: entity decoder7seg port map (temp, segments);
process (inco, rst)
begin
if inco = '1' then
CurrentPWMState <= CurrentPWMState + 1;
elsif rst='1' then
CurrentPWMState <= 0;
end if;
end process;
AN <= "1110";
end Behavioral;
Debouncing entity:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY debounce IS
PORT(pb, clock_100Hz : IN STD_LOGIC;
pb_debounced : OUT STD_LOGIC);
END debounce;
ARCHITECTURE a OF debounce IS
SIGNAL SHIFT_PB : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
-- Debounce Button: Filters out mechanical switch bounce for around 40Ms.
-- Debounce clock should be approximately 10ms
process
begin
wait until (clock_100Hz'EVENT) AND (clock_100Hz = '1');
SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1);
SHIFT_PB(3) <= NOT PB;
If SHIFT_PB(3 Downto 0)="0000" THEN
PB_DEBOUNCED <= '1';
ELSE
PB_DEBOUNCED <= '0';
End if;
end process;
end a;
And here is BCD to 7-segment decoder:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity decoder7seg is
port (
bcd: in std_logic_vector (3 downto 0);
segm: out std_logic_vector (6 downto 0));
end decoder7seg;
architecture Behavioral of decoder7seg is
begin
with bcd select
segm<= "0000001" when "0000", -- 0
"1001111" when "0001", -- 1
"0010010" when "0010", -- 2
"0000110" when "0011", -- 3
"1001100" when "0100", -- 4
"0100100" when "0101", -- 5
"0100000" when "0110", -- 6
"0001111" when "0111", -- 7
"0000000" when "1000", -- 8
"0000100" when "1001", -- 9
"1111110" when others; -- just - character
end Behavioral;
Does anyone see where I made my mistake(s) ?
I've tried that design on Spartan-3 Started board and it isn't working ... Every time I press the push button, I get crazy (random) values. The reset button is working properly.
Thanks !!!!
I guess the problem is here:
process (inco, rst)
begin
if inco = '1' then
CurrentPWMState <= CurrentPWMState + 1;
elsif rst='1' then
CurrentPWMState <= 0;
end if;
end process;
When rst='1' you will reset CurrentPWMState. But when inco='1' the you endlessly add 1 to CurrentPWMState. That's something like an asynchronous feedback loop through a latch. You should do something edge sensitive here. Probably you should capture inco using your clock signal, detect a 0->1 change and then add 1.
Agree with the previous answer.
A code like this should do the trick:
process (inco, ps, rst)
begin
if rst='1' then
CurrentPWMState <= '0';
prev_inco <= inco; -- This signal captures the previous value of inco
elsif ps'event and ps='1' then
if inco='1' and prev_inco='0' then -- Capture the flank rising.
CurrentPWMState <= CurrentPWMState + 1;
end if;
prev_inco <= inco;
end if;
end process;
I recognize I haven't tried the code (just coded in here) but I think it's ok.

Resources