Forum Discussion
Altera_Forum
Honored Contributor
16 years agoStrange block ram behavior
I have instantiated a dual port block ram in sopc builder. One end is connected to a nios2 processor, the other is connected to some custom vhdl code. The intent is for the nios2 to write to the ram ...
Altera_Forum
Honored Contributor
16 years agoI have a lot of vhdl code so not sure exactly what to post, but this module seems appropriate. This is the wrapper around the avalon bus coming from the block ram to my custom vhdl for reading from the ram.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Avalon_read is
generic(
ADDRS_WIDTH : integer;
DATA_WIDTH : integer
);
port(
-- user signals
clk : in std_logic;
read_en : std_logic;
data_addrs_in : in integer range 0 to 2**ADDRS_WIDTH-1;
data_out : out std_logic_vector(DATA_WIDTH-1 downto 0);
-- avalon signals
data_addrs_out : out std_logic_vector(31 downto 0);
data_length_out : out std_logic_vector(31 downto 0);
ctrl_go : out std_logic;
ctrl_done : in std_logic;
data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
data_ready : in std_logic;
data_read : out std_logic
);
end Avalon_read;
architecture arch of Avalon_read is
type tstate is (idle, send_ctrl, read, done);
signal state : tstate := idle;
begin
state_machine : process(clk)
begin
if(rising_edge(clk)) then
case state is
when idle =>
if(read_en='1') then
state <= send_ctrl;
end if;
when send_ctrl =>
state <= read;
when read =>
state <= done;
when done =>
state <= idle;
end case;
end if;
end process;
control_signals : process(state)
begin
case state is
when idle | done =>
ctrl_go <= '0';
data_addrs_out <= (others=>'Z');
data_length_out <= (others=>'Z');
data_read <= '0';
when send_ctrl =>
ctrl_go <= '1';
data_addrs_out <= conv_std_logic_vector(data_addrs_in*(DATA_WIDTH/8), 32);
data_length_out <= conv_std_logic_vector(DATA_WIDTH/8, 32); --x"00000004";
data_read <= '0';
when read =>
ctrl_go <= '0';
data_addrs_out <= (others=>'Z');
data_length_out <= (others=>'Z');
if(data_ready='1') then
data_read <= '1';
else
data_read <= '0';
end if;
end case;
end process;
datat_ff : process(clk)
begin
if(rising_edge(clk)) then
if(state=read) then
data_out <= data_in;
end if;
end if;
end process;
end arch;