Errore "Multiple drivers due to the non-tri-state driver"

Sezione dedicata al linguaggio di descrizione hardware per logiche programmabili

Errore "Multiple drivers due to the non-tri-state driver"

Postby flz47655 » 27 Aug 2012, 23:40

Ciao a tutti

Sto scrivendo una semplice CPU "from scratch", ho però il seguente errore da Quartus II che non riesco a capire..

Error (13076): The node "CPU3BIT:inst|addr[1]" has multiple drivers due to the non-tri-state driver "CPU3BIT:inst|data[7]"
Error (13076): The node "CPU3BIT:inst|data[6]" has multiple drivers due to the non-tri-state driver "CPU3BIT:inst|data[6]"
..errori per tutti gli elementi di CPU3BIT:inst|data

Sembrerebbe un problema dovuto al fatto che il segnale data è sia un ingresso sia un'uscita ed istruzioni consecutive come

Code: Select all
addr    <= data(5 downto 0);
data    <= reg;


diano dei problemi, commentando l'istruzione data <= reg; il tutto compila senza problemi.

Il codice problematico è nell'implementazione dell'istruzione STORE che scrive nella memoria il contenuto del registro REG. Per fare ciò carica l'indirizzo contenuto nell'istruzione (quindi nel segnale DATA) sulla linea ADDR collegata alla memoria e copia il contenuto del registro REG sul segnale DATA collegato anch'esso alla memoria.

Come posso risolvere questo problema?

Ecco il codice:

Code: Select all
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity CPU3BIT is
   port (
      data:   inout   std_logic_vector(7 downto 0);   -- Memory Data
      addr:   out std_logic_vector(5 downto 0);   -- Memory Address
      we:   out std_logic;                        -- Memory Write Enable
      d_reg: out std_logic_vector(7 downto 0);   -- Register for Debug
      rst:   in   std_logic;
      clk:   in   std_logic);
end;

architecture CPU_ARCH of CPU3BIT is
   signal   reg:      std_logic_vector(7 downto 0);      -- Register   
   signal    pc:      std_logic_vector(5 downto 0);      -- Program Counter
begin
   d_reg <= reg;
   process(clk, rst)
   begin
      if (rst = '0') then          
         reg   <= (others => '0');   -- Initialize register
         pc      <= (others => '0');   -- start execution at memory location 0
         addr   <=   (others => '0');   -- read memory at location 0
      elsif rising_edge(clk) then
         -- Increment clock
         pc   <= pc + 1;             
         
         -- Read data
         case data(7 downto 6) is
            -- Load
            when "00" =>
               we    <= '0';
               addr    <= data(5 downto 0);               
               reg    <= data; -- TODO: data is not readed data
            -- Store
            when "01" =>
               we    <= '1';               
               addr    <= data(5 downto 0);
               data    <= reg; -- Error (13076): The node "CPU3BIT:inst|addr[1]" has multiple drivers due to the non-tri-state driver "CPU3BIT:inst|data[7]"

            -- Add
            when "10" =>
               reg <= std_logic_vector(unsigned(reg) + unsigned(data));
            when others => null;
         end case;
         
      end if;
   end process;
   
end CPU_ARCH;


E l'implementazione della memoria sincrona che ho fatto

Code: Select all
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity MSRAM is
   port (
      clk   : in std_logic;
      data   : inout std_logic_vector(7 downto 0):= "ZZZZZZZZ";
      addr  : in std_logic_vector (5 downto 0) := "ZZZZZZ";     
      we    : in std_logic := 'Z';       -- write enable      
      rst   : in std_logic
   );
end;

architecture SRAM_ARCH of MSRAM is   
   -- memory is 4x8 bit
   -- memory block are ( _ TO _ ) to keep first block first in init
   -- memory bit are ( _ DOWNTO _ ) to keep LSB at right
   type memory is array (0 to 3) of std_logic_vector (7 downto 0);
   signal ram_block : memory;
   shared variable address : integer;
begin

   process(clk, rst)
   begin      
      -- todo: remove reset to syntetize to lpm_ram
      if (rst = '0') then         
         data    <= (others => 'Z');         
         -- pre-written bytes into memory
         ram_block <= (
         "00000011",      -- Load Addr 3
         "10000101",    -- Add 5
         "01000011",    -- Store Addr 3
         "10101010");   -- Addr 3 = 170
      elsif rising_edge(clk) then      
         -- decode address
         address := to_integer(unsigned(addr));
            
         --   Write
         if(we = '1') then
            ram_block(address) <= data(7 downto 0);   -- write data into ram_block
            data <= "ZZZZZZZZ";                        -- data is High Z
         elsif(we = '0') then
            -- Read            
            data <= ram_block(address);            
         else
            -- we High Z
            data <= "ZZZZZZZZ";
         end if;
      
      end if;
   end process;   
end SRAM_ARCH;
Last edited by flz47655 on 10 Oct 2012, 11:19, edited 3 times in total.
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: Semplice CPU

Postby flz47655 » 28 Aug 2012, 09:12

Mi sa che voglio fare troppe cose in un colpo di clock :D ...
E' possibile realizzare una CPU senza pipeline che esegue istruzioni in un solo colpo di clock?
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: Semplice CPU

Postby deluca » 28 Aug 2012, 13:32

se non hai risolto, appena ho tempo gli dò un'occhiatina al codice.

in un solo colpo di clock, cosa intendi, eseguire + istruzioni?

le risc eseguono 1 istruzione x ciclo di clock (di norma) senza pipeline.
Non mi è capitato mai di istanziare alu capaci di eseguire + di una istruzione per clk senza pipeline.

come mai questa richiesta?
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Semplice CPU

Postby flz47655 » 28 Aug 2012, 13:51

Ciao,
Purtroppo non ho ancora risolto.

Con eseguire più istruzioni intendevo eseguire più "operazioni" al fine di eseguire una intera istruzione (in questo caso l'istruzione STORE) in un solo colpo di clock.

Non voglio eseguire più istruzioni ma solamente un istruzione completa (formata da più operazioni) in un solo colpo di clock.

In questo caso per eseguire l'istruzione STORE che è del tipo 01AAAAAA dove 01 è il numero dell'istruzione e la seconda parte è l'indirizzo di memoria su cui copiare il registro unico del processore devo:

1) Settare WE su 1 per abilitare la scrittura della memoria
2) Copiare parte di DATA (ovvero AAAAAA) su ADDR per dire alla memoria dove voglio scrivere
3) Copiare REG in DATA per dare alla memoria i dati che devo copiare

Sembra però che ci siano problemi nell'eseguire in contemporanea le istruzioni 2 e 3 perché dovrei "leggere e scrivere" DATA in contemporanea..

Note: Il codice non è finito (e pieno di altre cose da sistemare) ma prima di andare avanti volevo capire come risolvere una situazione del genere

EDIT: Ho sistemato il codice postato della RAM
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: Semplice CPU

Postby flz47655 » 29 Aug 2012, 22:13

Ormai ho abbandonato questa versione e sto provando a fare le cose per benino: macchina a stati in una cpu multiciclo
Era interessante comunque, a parte il codice specifico, capire l'errore

Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16


Return to VHDL x FPGA

Who is online

Users browsing this forum: No registered users and 22 guests

cron