Forum Discussion
Strange 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 which will trigger operations in the vhdl so at initialization, the vhdl is constantly trying to read the ram while the nios2 is setting up and eventually writing to the ram. What should happen is the nios2 writes to the ram and immediately, the vhdl should begin processing. However, I am seeing some strange behavior where most of the time an additional read or write to the ram is required for the vhdl to properly read the values. Has anyone encountered such an issue?
4 Replies
- Altera_Forum
Honored Contributor
Nope.
Id post up your VHDL so we can find the problem. - Altera_Forum
Honored Contributor
I 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; - Altera_Forum
Honored Contributor
Silly question - you are bypassing any data cache ?
- Altera_Forum
Honored Contributor
yes, would that cause such a problem?