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;