Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

NIOS II write problem

Hi guys i'm new to the NIOS II system and FPGA's / VHDL.

I am trying to make a custom pio for software controlling the Avelon slave bus.

When i try to read from the custom qsys component it works ok, but when i write some thing to the component the compleet system hangs(nios).

Am i missing some thing or is there some thing wrong in VHDL or with the bus signals?

In models sim it looks all right when comparing with the Avelon Interface document.

See the code / vhdl below:

custom pio:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity spectr_pio is
  port(
    --Avalon slave bus
    clk         : in std_logic := '0';
    reset       : in std_logic := '0';
    chipselect  : in std_logic := '0';
      waitrequest : out std_logic := '0';
    address     : in std_logic_vector(4 downto 0) := (others => '0');
    write       : in std_logic := '0';
    writedata   : in std_logic_vector(31 downto 0) := (others => '0');
    read        : in std_logic := '0';
    readdata    : out std_logic_vector(31 downto 0) := (others => '0');
    --in
    ireal : in std_logic_vector(15 downto 0) := (others => '0');
    iimag : in std_logic_vector(15 downto 0) := (others => '0');
    ictrl : in std_logic_vector(5 downto 0) := (others => '0');
    iexp  : in std_logic_vector(5 downto 0) := (others => '0');
    --out
    octrl : out std_logic_vector(8 downto 0) := (others => '0');
    oreal : out std_logic_vector(15 downto 0) := (others => '0');
    oimag : out std_logic_vector(15 downto 0) := (others => '0')
  );
end entity spectr_pio;
architecture rtl of spectr_pio is
  --Constants
  --Read write addressess
  constant ADDR_IREAL : integer := 0;
  constant ADDR_IIMAG : integer := 1;
  constant ADDR_ICTRL : integer := 2;
  constant ADDR_IEXP  : integer := 3;
  
  constant ADDR_OREAL : integer := 4;
  constant ADDR_OIMAG : integer := 5;
  constant ADDR_OCTRL : integer := 6;
    
  signal wait_req_active_wr : std_logic := '0';
  signal wait_req_active_rd : std_logic := '0';
  
  begin
  
  --Write to pio
  process(clk, write, chipselect, address, writedata)
    variable addr_sel : integer := 0;
    begin
    if(rising_edge(clk)) then
      if(write = '1' and chipselect = '1') then
        addr_sel := to_integer(unsigned(address));
          --It is necessary to delay the bus for one cycle
          if(wait_req_active_wr = '0') then
            wait_req_active_wr <= '1';
          else
            wait_req_active_wr <= '0';
          end if;
          
        case addr_sel is
          when ADDR_OREAL => oreal <= writedata(15 downto 0);
          when ADDR_OIMAG => oimag <= writedata(15 downto 0);
          when ADDR_OCTRL => octrl <= writedata(8 downto 0);
          when others => null;
        end case;
      end if;
    end if;
  end process;
  
  --Read from pio
  process(clk, read, chipselect, address)
    variable addr_sel : integer := 0;
    begin
    if(rising_edge(clk)) then
      if(read = '1' and chipselect = '1') then
        addr_sel := to_integer(unsigned(address));
          --It is necessary to delay the bus for one cycle
          if(wait_req_active_rd = '0') then
            wait_req_active_rd <= '1';
          else
            wait_req_active_rd <= '0';
          end if;
          
        case addr_sel is
          when ADDR_IREAL => readdata <= X"0000" & ireal;
          when ADDR_IIMAG => readdata <= X"0000" & iimag;
          when ADDR_ICTRL => readdata <= X"000000" & "00" & ictrl;
          when ADDR_IEXP  => readdata <= X"000000" & "00" & iexp;
          when others => readdata <= X"00000000";
        end case;
        --readdata <= (X"F00000" & "000" & address);
      end if;
    end if;
  end process;
  
  --If one of the process blocks wants to wait...
  waitrequest <= wait_req_active_rd or wait_req_active_wr;
  --pio <= data;
    
end architecture rtl;

some test code:

    //First read
    volatile uint32_t ireal = *(baseAddr + 0);
    volatile uint32_t iimag = *(baseAddr + 1);
    volatile uint32_t ictrl = *(baseAddr + 2);
    volatile uint32_t iexp = *(baseAddr + 3);
    *(baseAddr + 1) = 0x0000FEEF;//The code hangs here on instruction "stw r2,0(r3)"
    ireal = *(baseAddr + 0);
    *(baseAddr + 6) = 0x00001234;//Write oimag
    //Now reread
    ireal = *(baseAddr + 0);
    iimag = *(baseAddr + 1);
No RepliesBe the first to reply