Forum Discussion

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

Programming MAX 10 with .mif

I'm trying to program a 10M50 on the Altera Development Kit. It's programming fine, but I'm not getting the expected readout over UART (I keep getting a semi-random single number continously), so I'd like to confirm that I'm filling the RAM correctly. The RAM is a 2-port altsyncram from the IP generator, and simulates correctly.

Can anyone see if I'm doing it right?

https://s30.postimg.org/4rk3103vh/programmer.png (https://postimg.org/image/4rk3103vh/)

The .mif file:

DEPTH = 12500;                -- The size of memory in words
WIDTH = 12;                   -- The size of data in bits
ADDRESS_RADIX = HEX;          -- The radix for address values
DATA_RADIX = HEX;             -- The radix for data values
CONTENT                       -- start of (address : data pairs)
BEGIN
                              -- memory address : data
-- 1..12500
0000 : 0001;
0001 : 0002;
0002 : 0003;
0003 : 0004;
0004 : 0005;
0005 : 0006;
0006 : 0007;
0007 : 0008;

And it goes on like that up to 12499.

The .qsf file contains:

set_global_assignment -name MIF_FILE ../source/RAM_init.mif

And in Quartus, this option is selected:

Assignments -> Device -> Device and Pin Options -> Configuration -> Configuration Mode: Single Uncompressed Image with Memory Initialization (512Kbits UFM)

The RAM:

LIBRARY ieee;USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
ENTITY RAM IS
    PORT
    (
        data        : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
        rdaddress        : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
        rdclock        : IN STD_LOGIC ;
        rden        : IN STD_LOGIC  := '1';
        wraddress        : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
        wrclock        : IN STD_LOGIC  := '1';
        wren        : IN STD_LOGIC  := '0';
        q        : OUT STD_LOGIC_VECTOR (11 DOWNTO 0)
    );
END RAM;
ARCHITECTURE SYN OF ram IS
    SIGNAL sub_wire0    : STD_LOGIC_VECTOR (11 DOWNTO 0);
BEGIN
    q    <= sub_wire0(11 DOWNTO 0);
    altsyncram_component : altsyncram
    GENERIC MAP (
        address_aclr_b => "NONE",
        address_reg_b => "CLOCK1",
        clock_enable_input_a => "BYPASS",
        clock_enable_input_b => "BYPASS",
        clock_enable_output_b => "BYPASS",
        init_file => "../source/RAM_init.mif",
        intended_device_family => "MAX 10",
        lpm_type => "altsyncram",
        numwords_a => 12500,
        numwords_b => 12500,
        operation_mode => "DUAL_PORT",
        outdata_aclr_b => "NONE",
        outdata_reg_b => "CLOCK1",
        power_up_uninitialized => "FALSE",
        rdcontrol_reg_b => "CLOCK1",
        widthad_a => 14,
        widthad_b => 14,
        width_a => 12,
        width_b => 12,
        width_byteena_a => 1
    )
    PORT MAP (
        address_a => wraddress,
        address_b => rdaddress,
        clock0 => wrclock,
        clock1 => rdclock,
        data_a => data,
        rden_b => rden,
        wren_a => wren,
        q_b => sub_wire0
    );
END SYN;

/edit: I tried the In-System Memory Content Editor, but it does not detect the RAM, which I'm thinking is a clue.

https://s29.postimg.org/4e30d5lgz/memory_editor.png (https://postimg.org/image/4e30d5lgz/)

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes, that's a clue. RAM looks OK. Post the code where you've instantiated it.

    Cheers,

    Alex
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Alex,

    The RAM is instantiated in ADC_RAM which in turn is instantiated in UTTM.

    library IEEE;
    use IEEE.Std_logic_1164.all;
    use IEEE.Numeric_std.all;
    entity ADC_RAM is port (
      clock       : in  std_logic;                      -- input from higher level
      async_reset : in  std_logic;                      -- input from higher level
      ADC_inclock : in  std_logic;                      -- input from pin
      ADC_in      : in  std_logic_vector  (5 downto 0); -- input from pin
      ADC_oe      : out std_logic;                      -- output to pin
      ADC_SCL     : out  std_logic;                     -- output to pin
      ADC_SDA     : inout std_logic;                    -- bidirecional to pin
      ADC_SENn    : out std_logic;                      -- output to pin
      ADC_OVR     : in  std_logic;                      -- input from pin
      rdaddress   : in  std_logic_vector (13 downto 0); -- input from higher level
      rden        : in  std_logic := '1';               -- input from higher level
      q           : out std_logic_vector (11 downto 0); -- output to higher level
      activation  : in  std_logic;                      -- input from higher level
      completion  : out std_logic);                     -- output to higher level
    end entity ADC_RAM;
    architecture RTL of ADC_RAM is
      -- RAM
      component RAM
        port
        (
          data       : in std_logic_vector (11 downto 0);
          rd_aclr    : in std_logic  := '0';
          rdaddress  : in std_logic_vector (13 downto 0);
          rdclock    : in std_logic ;
          rden       : in std_logic  := '1';
          wraddress  : in std_logic_vector (13 downto 0);
          wrclock    : in std_logic  := '1';
          wren       : in std_logic  := '0';
          q          : out std_logic_vector (11 downto 0)
        );
      end component RAM;
      -- FSM
      type statetype is (S0, S1, S2, S3, S4);
      signal state, nextstate  : statetype;
      -- Misc                                      Clock domain:
      signal clock_Core            : std_logic; -- Core
      signal clock_ADC             : std_logic; -- ADC
      signal clock_ADC_config      : std_logic; -- ADC
      signal reset_Core            : std_logic; -- Core
      signal reset_ADC             : std_logic; -- ADC
      signal RAM_filled_ADC        : std_logic; -- ADC
      signal LVDStoRAM_en_ADC      : std_logic; -- ADC
      signal RAM_filled_Core       : std_logic; -- Core
      signal LVDStoRAM_en_Core     : std_logic; -- Core
      signal ADC_wait_start        : std_logic; -- ADC
      signal ADC_wait_done         : std_logic; -- ADC
      signal ADC_config_start_Core : std_logic; -- Core
      signal ADC_config_start_ADC  : std_logic; -- ADC
      signal ADC_config_done_Core  : std_logic; -- Core
      signal ADC_config_done_ADC   : std_logic; -- ADC
      -- RAM
      signal data_sig          : std_logic_vector (11 downto 0);
    --  signal rdaddress_sig    : std_logic_vector (13 downto 0);
    --  signal rdclock_sig      : std_logic;
    --  signal rden_sig         : std_logic;
      signal wraddress_sig     : std_logic_vector (13 downto 0);
    --  signal wrclock_sig      : std_logic;
      signal wren_sig          : std_logic;
    --  signal q_sig            : std_logic_vector (11 downto 0)
    begin
      -- RAM
      RAM_inst : RAM port map (
          data      => data_sig,      -- internal
          rd_aclr   => reset_Core,    -- port through async_reset_sync_release process
          rdaddress => rdaddress,     -- port
          rdclock   => clock_Core,    -- port through signal
          rden      => rden,          -- port
          wraddress => wraddress_sig, -- internal
          wrclock   => clock_ADC,     -- port through signal
          wren      => wren_sig,      -- internal
          q         => q              -- port
        );
    

    library IEEE;
    use IEEE.Std_logic_1164.all;
    use IEEE.Numeric_std.all;
    entity UTTM is
      port ( 
        CPU_RESETn     : in  std_logic;                    -- 3.3V LVCMOS
        CLK_50_MAX10   : in  std_logic;                    -- 2.5V
        CLK_25_MAX10   : in  std_logic;                    -- 2.5V
        CLK_LVDS_125_p : in  std_logic;                    -- 2.5V
        CLK_10_ADC     : in  std_logic;                    -- 2.5V
        HSMC_CLK_IN_p  : in  std_logic;                    -- LVDS (CLKOUTM) / PINS: V10, V9
        HSMC_RX_D_p    : in  std_logic_vector(5 downto 0); -- LVDS / PINS: AB7, Y4, AB5, W13, AB15, Y16, AB6, Y3, AA5, W12, AA14, AA15
        HSMC_SCL       : out std_logic;                    -- 2.5V / PIN: Y18
        HSMC_SDA       : inout std_logic;                  -- 2.5V / PIN: AA19
        HSMC_SENn      : out std_logic := '0';             -- 2.5V / PIN: Y7
        HSMC_OVR       : in  std_logic;                    -- 2.5V / PIN: Y8
      );
    end entity UTTM;
    architecture RTL of UTTM is
      component ADC_RAM port (
        clock          : in  std_logic;
        async_reset    : in  std_logic;
        ADC_inclock    : in  std_logic;
        ADC_in         : in  std_logic_vector(5 downto 0);
        ADC_oe         : out std_logic;
        ADC_SCL        : out std_logic;
        ADC_SDA        : inout std_logic;
        ADC_SENn       : out std_logic;
        ADC_OVR        : in  std_logic;
        rdaddress      : in  std_logic_vector(13 downto 0);
        rden           : in  std_logic;
        q              : out std_logic_vector(11 downto 0);
        activation     : in  std_logic;
        completion     : out std_logic
        );
      end component;
      -- FSM
      type statetype is (S0, S1, S2, S3);
      signal state, nextstate  : statetype;
      signal statecode         : std_logic_vector(7 downto 0) := (others => '0');
      -- ADC/RAM
      signal RAM_address       : std_logic_vector(13 downto 0) := (others => '0'); -- output
      signal RAM_read_en       : std_logic := '0';                                 -- output
      signal RAM_dataout       : std_logic_vector(11 downto 0);                    -- input
      signal ADC_activation    : std_logic := '0';                                 -- output
      signal ADC_completion    : std_logic;                                        -- input
      --constant ADC_wait_cycles : natural := 13; -- "wait for valid ADC data" delay = 100 ns
    begin
      ADC_RAM_instance : ADC_RAM port map (
        clock       => CLK_LVDS_125_p,
        async_reset => not CPU_RESETn,
        ADC_inclock => HSMC_CLK_IN_p,
        ADC_in      => HSMC_RX_D_p,
        ADC_oe      => open,
        ADC_SCL     => HSMC_SCL,
        ADC_SDA     => HSMC_SDA,
        ADC_SENn    => HSMC_SENn,
        ADC_OVR     => HSMC_OVR,
        rdaddress   => RAM_address,
        rden        => RAM_read_en,
        q           => RAM_dataout,
        activation  => ADC_activation,
        completion  => ADC_completion
      );

    /edit: Added the "rd_aclr" to the RAM compared to the top post to see if that fixed anything, but there was no difference.

    LIBRARY ieee;USE ieee.std_logic_1164.all;
    LIBRARY altera_mf;
    USE altera_mf.altera_mf_components.all;
    ENTITY RAM IS
        PORT
        (
            data        : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
            rd_aclr        : IN STD_LOGIC  := '0';
            rdaddress        : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
            rdclock        : IN STD_LOGIC ;
            rden        : IN STD_LOGIC  := '1';
            wraddress        : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
            wrclock        : IN STD_LOGIC  := '1';
            wren        : IN STD_LOGIC  := '0';
            q        : OUT STD_LOGIC_VECTOR (11 DOWNTO 0)
        );
    END RAM;
    ARCHITECTURE SYN OF ram IS
        SIGNAL sub_wire0    : STD_LOGIC_VECTOR (11 DOWNTO 0);
    BEGIN
        q    <= sub_wire0(11 DOWNTO 0);
        altsyncram_component : altsyncram
        GENERIC MAP (
            address_aclr_b => "CLEAR1",
            address_reg_b => "CLOCK1",
            clock_enable_input_a => "BYPASS",
            clock_enable_input_b => "BYPASS",
            clock_enable_output_b => "BYPASS",
            init_file => "../../source/RAM_init.mif",
            intended_device_family => "MAX 10",
            lpm_type => "altsyncram",
            numwords_a => 12500,
            numwords_b => 12500,
            operation_mode => "DUAL_PORT",
            outdata_aclr_b => "CLEAR1",
            outdata_reg_b => "CLOCK1",
            power_up_uninitialized => "FALSE",
            ram_block_type => "M9K",
            rdcontrol_reg_b => "CLOCK1",
            widthad_a => 14,
            widthad_b => 14,
            width_a => 12,
            width_b => 12,
            width_byteena_a => 1
        )
        PORT MAP (
            aclr1 => rd_aclr,
            address_a => wraddress,
            address_b => rdaddress,
            clock0 => wrclock,
            clock1 => rdclock,
            data_a => data,
            rden_b => rden,
            wren_a => wren,
            q_b => sub_wire0
        );
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I tried the In-System Memory Content Editor, but it does not detect the RAM, which I'm thinking is a clue.

    --- Quote End ---

    It hardly can unless "ENABLE_RUNTIME_MOD=YES" is set for the RAM instance. And it can't work for dual-port RAM because one port is needed for the JTAG interface.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't see ENABLE_RUNTIME_MOD in the RAM HDL, so what should I map to in the RAM instance?

    I could make a quick single-port just to check.

    Is there another way I can check the (dual-port) RAM functionality?

    As I mentioned I already simulated it successfully, writing it full it then reading it.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I simplified the RTL considerably, and now it's just outputting zeroes over UART :confused:

    library IEEE;
    use IEEE.Std_logic_1164.all;
    use IEEE.Numeric_std.all;
    entity UTTM is
      port ( 
        CPU_RESETn     : in  std_logic;                    -- 3.3V LVCMOS
        CLK_50_MAX10   : in  std_logic;                    -- 2.5V
        CLK_25_MAX10   : in  std_logic;                    -- 2.5V
        CLK_LVDS_125_p : in  std_logic;                    -- 2.5V
        CLK_10_ADC     : in  std_logic;                    -- 2.5V
        USER_LED       : out std_logic_vector(4 downto 0); -- 1.5V
        USER_PB        : in  std_logic_vector(3 downto 0); -- 1.5V
        USER_DIPSW     : in  std_logic_vector(4 downto 0); -- 1.5V
        UART_TX        : out std_logic                     -- 2.5V
      );
    end entity UTTM;
    architecture RTL of UTTM is
      -- UART
      component uart_simple port (
        i_clk          : in  std_logic;
        I_clk_baud_count : in  std_logic_vector(15 downto 0);
        i_reset        : in  std_logic;
        i_txdata       : in  std_logic_vector(7 downto 0);
        i_txsig        : in  std_logic;
        o_txrdy        : out std_logic;
        o_tx           : out std_logic
        );
      end component; 
      -- RAM
      component RAM port (
        data       : in std_logic_vector (11 downto 0);
        rd_aclr    : in std_logic  := '0';
        rdaddress  : in std_logic_vector (13 downto 0);
        rdclock    : in std_logic ;
        rden       : in std_logic  := '1';
        wraddress  : in std_logic_vector (13 downto 0);
        wrclock    : in std_logic  := '1';
        wren       : in std_logic  := '0';
        q          : out std_logic_vector (11 downto 0)
        );
      end component RAM;
      -- FSM
      type statetype is (S0, S1, S2);
      signal state, nextstate  : statetype;
      signal statecode         : std_logic_vector(7 downto 0) := (others => '0');
      -- UART
      signal txdata            : std_logic_vector(7 downto 0) := (others => '0');
      signal txsig             : std_logic := '0';
      signal txrdy             : std_logic := '0';
      signal rdaddress         : std_logic_vector (13 downto 0);
      signal rden              : std_logic;
      signal q                 : std_logic_vector (11 downto 0);
      signal TX_activation     : std_logic := '0';
      signal TX_completion     : std_logic := '0';
    begin
      uart_instance : uart_simple port map (
        I_clk            => CLK_LVDS_125_p,
        I_clk_baud_count => X"32DD", -- 9600 bps @ 125 MHz clock
        --I_clk_baud_count => X"043D", -- 115200 bps @ 125 MHz clock
        --I_clk_baud_count => X"0088", -- 921600 bps @ 125 MHz clock
        I_reset          => not CPU_RESETn,
        I_txdata         => txdata,
        i_txsig          => txsig,
        o_txrdy          => txrdy,
        O_tx             => UART_TX
      );
      -- RAM
      RAM_inst : RAM port map (
        data      => (others => '0'),
        rd_aclr   => not CPU_RESETn,
        rdaddress => rdaddress,
        rdclock   => CLK_LVDS_125_p,
        rden      => rden,
        wraddress => (others => '0'),
        wrclock   => '0',
        wren      => '0',
        q         => q
      );
      -- may need to add a first-run variable as RAM has not yet been read out for first UART transmission
      tx_RAM_process : process (CLK_LVDS_125_p, CPU_RESETn) 
      variable i : integer := 0;
      begin
        if CPU_RESETn = '0' then
          i             := 0;
          txdata        <= (others => '0');
          txsig         <= '0';
          rden          <= '0';
          rdaddress     <= (others => '0');
          TX_completion <= '0';
        elsif rising_edge(CLK_LVDS_125_p) then
          if txrdy = '1' and TX_activation = '1' then
            if i <= (12500-1) then -- output loop begin
              i             := i + 1;
              txdata        <= q(11 downto 4);
              txsig         <= '1';
              rden          <= '1';
              rdaddress     <= std_logic_vector(to_unsigned(i,14));
              TX_completion <= '0';
            else
              i             := 0;
              txdata        <= (others => '0');
              txsig         <= '0';
              rden          <= '0';
              rdaddress     <= (others => '0');
              TX_completion <= '1';
            end if;                -- output loop end
          end if;
        end if;
      end process;
      FSM_clock_process : process (CLK_LVDS_125_p, CPU_RESETn) is
      begin
        if rising_edge(CLK_LVDS_125_p) then
          if CPU_RESETn = '0' then
            state <= S0;
          else
            state <= nextstate;
          end if;
        end if;
      end process FSM_clock_process;
      FSM_io_process : process (CPU_RESETn, state, TX_completion, USER_PB) is
      begin
        if CPU_RESETn = '0' then
          TX_activation        <= '0';
          nextstate            <= S0;
          USER_LED(3 downto 0) <= "1111";
        else
          -- default assignments
          TX_activation        <= '0';
          nextstate            <= state;
          USER_LED(3 downto 0) <= "1111";
          case state is
            -- idle state after reset
            when S0 =>
              USER_LED(3 downto 0) <= "1110";
              if USER_PB = "1110" then
                TX_activation <= '1';
                nextstate <= S1;
              end if;
            when S1 =>
              USER_LED(3 downto 0) <= "1100";
              if TX_completion = '1' then
                TX_activation <= '0';
                nextstate <= S2;
              end if;
            when S2 =>
              USER_LED(3 downto 0) <= "1000";
              if USER_PB = "0111" then
                nextstate <= S0;
              end if;
          end case;
        end if;
      end process FSM_io_process;
    end architecture RTL;