Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Error Message: Can't Handle Registered Multi Driver

Status
Not open for further replies.

Mecanico

Technical User
Feb 8, 2003
2
MX
I have that message. I believe it appears when a signal is driven by more than one process... But I cant seem to find where. What are the most common cases in which this kind of errors appear?

In my case it appears while handling a couple of std_logic_vectors, to be exact, in the I/O of a file register, and a couple of 16 bit registers.

Any information about this error would be gladly apreciated.

Here is a snipet of the code:
SIGNAL MEMORIA1: MEMORIA:=("00000000","00000001","00000010","00000011",
"00000100","00000101","00000110","00000111",
"00001000","00001001","00001010","00001011",
"00001100","00001101","00001110","00001111");
BEGIN
PROCESS(ADDR_B, ADDR_A,CLK,RE,RST,MEMORIA1)
VARIABLE CELDA: INTEGER;
BEGIN
IF RISING_EDGE(CLK) THEN
IF (WE='1') THEN
CELDA:=conv_integer(ADDR_I);
-- MEMORIA1(CELDA)<=DATO_I;
END IF;
END IF;
IF(RE='1') THEN
DATO_A<=MEMORIA1(conv_integer(ADDR_A));
DATO_B<=MEMORIA1(conv_integer(ADDR_B));
END IF;
IF(RST='1') THEN
MEMORIA1<=(&quot;00000000&quot;,&quot;00000001&quot;,&quot;00000010&quot;,&quot;00000011&quot;,
&quot;00000100&quot;,&quot;00000101&quot;,&quot;00000110&quot;,&quot;00000111&quot;,
&quot;00001000&quot;,&quot;00001001&quot;,&quot;00001010&quot;,&quot;00001011&quot;,
&quot;00001100&quot;,&quot;00001101&quot;,&quot;00001110&quot;,&quot;00001111&quot;);
END IF;

Curiously, commenting the line shown solves the problem for the memoria1 vector. Why is that?

I hope I gave enough info about this. Im using Cypress Warp.

Thanks in advance
 
Hi,

The error you are getting is absolutely legal.

The memory element located by the value CELDA is written into with the data DATO_I under the clock edge during the write enable.

The same memory array, which consists of the above mentioned memory element is again written into under the RESET condition.

In effect, the net MEMORIA1(CELDA) is driven by both DATO_I as well as one of the constants in the MEMORIA1 table-entry.

I would suggest you to change your coding style as follows to make your code error-free as well as more efficient.

-- _______________________________________
-- Process to WRITE into memory

PROCESS(ADDR_B, ADDR_A,CLK,RE,RST,MEMORIA1)
VARIABLE CELDA: INTEGER;
BEGIN
IF(RST='1') THEN
MEMORIA1<=(&quot;00000000&quot;,&quot;00000001&quot;,&quot;00000010&quot;,&quot;00000011&quot;,
&quot;00000100&quot;,&quot;00000101&quot;,&quot;00000110&quot;,&quot;00000111&quot;,
&quot;00001000&quot;,&quot;00001001&quot;,&quot;00001010&quot;,&quot;00001011&quot;,
&quot;00001100&quot;,&quot;00001101&quot;,&quot;00001110&quot;,&quot;00001111&quot;);
ELSIF RISING_EDGE(CLK) THEN
IF (WE='1') THEN
CELDA:=conv_integer(ADDR_I);
MEMORIA1(CELDA)<=DATO_I;
END IF;
END IF;END PROCESS;

-- Process to READ from memory

PROCESS(MEMORIA1, ADDR_A, ADDR_B)
BEGIN
IF(RE='1') THEN
DATO_A<=MEMORIA1(conv_integer(ADDR_A));
DATO_B<=MEMORIA1(conv_integer(ADDR_B));
END IF;
END IF;
END PROCESS;

--________________________________________

The second process, however, will result in a latch since there is no ELSE to the IF (RE='1') part. To avoid latches being inferred, make the process synchronous to clock.

 
Hi,

The error you are getting is absolutely legal.

The memory element located by the value CELDA is written into with the data DATO_I under the clock edge during the write enable.

The same memory array, which consists of the above mentioned memory element is again written into under the RESET condition.

In effect, the net MEMORIA1(CELDA) is driven by both DATO_I as well as one of the constants in the MEMORIA1 table-entry.

I would suggest you to change your coding style as follows to make your code error-free as well as more efficient.

-- _______________________________________
-- Process to WRITE into memory

PROCESS(ADDR_B, ADDR_A,CLK,RE,RST,MEMORIA1)
VARIABLE CELDA: INTEGER;
BEGIN
IF(RST='1') THEN
MEMORIA1<=(&quot;00000000&quot;,&quot;00000001&quot;,&quot;00000010&quot;,&quot;00000011&quot;,
&quot;00000100&quot;,&quot;00000101&quot;,&quot;00000110&quot;,&quot;00000111&quot;,
&quot;00001000&quot;,&quot;00001001&quot;,&quot;00001010&quot;,&quot;00001011&quot;,
&quot;00001100&quot;,&quot;00001101&quot;,&quot;00001110&quot;,&quot;00001111&quot;);
ELSIF RISING_EDGE(CLK) THEN
IF (WE='1') THEN
CELDA:=conv_integer(ADDR_I);
MEMORIA1(CELDA)<=DATO_I;
END IF;
END IF;END PROCESS;

-- Process to READ from memory

PROCESS(MEMORIA1, ADDR_A, ADDR_B, RE)
BEGIN
IF(RE='1') THEN
DATO_A<=MEMORIA1(conv_integer(ADDR_A));
DATO_B<=MEMORIA1(conv_integer(ADDR_B));
END IF;
END IF;
END PROCESS;

--________________________________________

The second process, however, will result in a latch since there is no ELSE to the IF (RE='1') part. To avoid latches being inferred, make the process synchronous to clock.

 
Thanks for answering RVSachin.

After making the changes you suggested, I came into another problem:

Unable to find compatible location for IOCell &quot;We&quot;.

Heres the code again, Mind the READ process. Thats how its supposed to work :p (yeap, it's homework,must read two values async, and 1 value sync. I guess its to demonstrate the problems asociated with the aproach :p)

BEGIN
RESET:pROCESS(RST,MEMORIA1,CLK)
VARIABLE CELDA: INTEGER;
BEGIN
IF (RST='1') THEN
MEMORIA1<=(&quot;00000000&quot;,&quot;00000001&quot;,&quot;00000010&quot;,&quot;00000011&quot;,
&quot;00000100&quot;,&quot;00000101&quot;,&quot;00000110&quot;,&quot;00000111&quot;,
&quot;00001000&quot;,&quot;00001001&quot;,&quot;00001010&quot;,&quot;00001011&quot;,
&quot;00001100&quot;,&quot;00001101&quot;,&quot;00001110&quot;,&quot;00001111&quot;);

ELSIF RISING_EDGE(CLK) THEN
IF(WE='1') THEN
CELDA:=conv_integer(ADDR_I);
MEMORIA1(CELDA)<=DATO_I;
END IF;
END IF;
END PROCESS;

READ:pROCESS(ADDR_A,ADDR_B,RE,MEMORIA1)
BEGIN
IF RISING_EDGE(RE) THEN
DATO_A<=MEMORIA1(conv_integer(ADDR_A));
DATO_B<=MEMORIA1(conv_integer(ADDR_B));
END IF;
END PROCESS;
END COMPORTAMIENTO_ARCHIVO_REGISTRO;

Thanks in advance
 
I didn't see any error on my side.
This is my complete code for your reference:


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ram is
port(
rst, we, re, clk: in std_logic;
dato_i: in std_logic_vector(7 downto 0);
addr_i, addr_a, addr_b: in std_logic_vector(3 downto 0);
dato_a, dato_b: out std_logic_vector(7 downto 0));
end ram;

architecture comportamiento_archivo_registro of ram is

type mem is array (0 to 15) of std_logic_vector(7 downto 0);
signal memoria1: mem;

begin
reset:process(rst,memoria1,clk)
variable celda: integer;
begin
if (rst='1') then
memoria1<=(&quot;00000000&quot;,&quot;00000001&quot;,&quot;00000010&quot;,&quot;00000011&quot;,
&quot;00000100&quot;,&quot;00000101&quot;,&quot;00000110&quot;,&quot;00000111&quot;,
&quot;00001000&quot;,&quot;00001001&quot;,&quot;00001010&quot;,&quot;00001011&quot;,
&quot;00001100&quot;,&quot;00001101&quot;,&quot;00001110&quot;,&quot;00001111&quot;);

elsif rising_edge(clk) then
if(we='1') then
celda:=conv_integer(addr_i);
memoria1(celda)<=dato_i;
end if;
end if;
end process;

read:process(addr_a,addr_b,re,memoria1)
begin
if rising_edge(re) then
dato_a<=memoria1(conv_integer(addr_a));
dato_b<=memoria1(conv_integer(addr_b));
end if;
end process;
end comportamiento_archivo_registro;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top