Author Topic: Problems with Quartus Modelsim simulation  (Read 1871 times)

0 Members and 1 Guest are viewing this topic.

Offline e0ne199Topic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: id
Problems with Quartus Modelsim simulation
« on: March 04, 2024, 06:22:12 am »
hello everyone, I am trying to make a RAM using the code below :
RAM :
Code: [Select]
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;

entity project1 is
   Port ( RAM_DATA_IN_OUT  : inout STD_LOGIC_VECTOR (7 downto 0);
RAM_ADDR         : in std_logic_vector(7 downto 0);
RAM_WR_EN        : in std_logic;
RAM_OUT_EN       : in std_logic;
RAM_CLK          : in std_logic
);

end entity;

architecture Behavioral of project1 is
   component ram_entity is
    port (
        clk              :in    std_logic;                      -- Clock Input
        address          :in    std_logic_vector (7 downto 0);  -- address Input
        data_line        :inout std_logic_vector (7 downto 0);  -- data bi-directional       
        write_enable     :in    std_logic;                      -- Write Enable/Read Enable
  output_enable :in   std_logic -- output enable
        );
end component;

begin
    ----------------Code Starts Here------------------
mem_module : ram_entity port map(
  clk=>RAM_CLK,
  address=>RAM_ADDR,
  data_line=>RAM_DATA_IN_OUT,
  write_enable=>RAM_WR_EN,
  output_enable=>RAM_OUT_EN
);
 
end Behavioral;


Entity :
Code: [Select]
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;

entity ram_entity is
    port (
        clk              :in    std_logic;                      -- Clock Input
        address          :in    std_logic_vector (7 downto 0);  -- address Input
        data_line        :inout std_logic_vector (7 downto 0);  -- data bi-directional       
        write_enable     :in    std_logic;                      -- Write Enable/Read Enable
  output_enable :in   std_logic -- output enable
        );
end entity;
architecture Behavioral of ram_entity is
    ----------------Internal variables----------------
    type RAM is array (0 to 255) of std_logic_vector (7 downto 0);
    signal mem : RAM := (others => (others => '0'));--clear RAM on startup
begin

    ----------------Code Starts Here------------------
    -- Memory Write Block
    -- Write Operation : When write_enable = 1

    MEM_WRITE:
    process (clk) begin
        if (rising_edge(clk)) then
if ( write_enable = '1' and output_enable = '0') then
                mem(conv_integer(address)) <= data_line;
            end if;
        end if;
    end process;

-- Tri-State Buffer control
    -- output : When write_enable = 0, output_enable = 1
    data_line <= mem(conv_integer(address)) when (write_enable = '0' and output_enable = '1')else (others=>'Z');


end Behavioral;


Test bench :
Code: [Select]
-- Copyright (C) 2019  Intel Corporation. All rights reserved.
-- Your use of Intel Corporation's design tools, logic functions
-- and other software and tools, and any partner logic
-- functions, and any output files from any of the foregoing
-- (including device programming or simulation files), and any
-- associated documentation or information are expressly subject
-- to the terms and conditions of the Intel Program License
-- Subscription Agreement, the Intel Quartus Prime License Agreement,
-- the Intel FPGA IP License Agreement, or other applicable license
-- agreement, including, without limitation, that your use is for
-- the sole purpose of programming logic devices manufactured by
-- Intel and sold by Intel or its authorized distributors.  Please
-- refer to the applicable agreement for further details, at
-- https://fpgasoftware.intel.com/eula.

-- ***************************************************************************
-- This file contains a Vhdl test bench template that is freely editable to   
-- suit user's needs .Comments are provided in each section to help the user 
-- fill out necessary details.                                               
-- ***************************************************************************
-- Generated on "02/20/2024 05:17:47"
                                                           
-- Vhdl Test Bench template for design  :  project1
--
-- Simulation tool : ModelSim-Altera (VHDL)
--

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;                               


ENTITY project1_vhd_tst IS
END project1_vhd_tst;
ARCHITECTURE project1_arch OF project1_vhd_tst IS
-- constants                                                 
-- signals                                                   
SIGNAL RAM_ADDR : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RAM_CLK : STD_LOGIC;
SIGNAL RAM_DATA_IN_OUT : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RAM_OUT_EN : STD_LOGIC;
SIGNAL RAM_WR_EN : STD_LOGIC;

COMPONENT project1
PORT (
RAM_ADDR : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
RAM_CLK : IN STD_LOGIC;
RAM_DATA_IN_OUT : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
RAM_OUT_EN : IN STD_LOGIC;
RAM_WR_EN : IN STD_LOGIC
);
END COMPONENT;
BEGIN
i1 : project1
PORT MAP (
-- list connections between master ports and signals
RAM_ADDR => RAM_ADDR,
RAM_CLK => RAM_CLK,
RAM_DATA_IN_OUT => RAM_DATA_IN_OUT,
RAM_OUT_EN => RAM_OUT_EN,
RAM_WR_EN => RAM_WR_EN
);
mem_test : PROCESS                                           
-- variable declarations     
   
BEGIN

  RAM_WR_EN <= '0';
  RAM_OUT_EN <='1';
  RAM_ADDR <= "00000000";
  RAM_DATA_IN_OUT <= "00000000";
  wait for 100 ns;
  -- start reading data from RAM
  for i in 0 to 5 loop
  RAM_ADDR <= RAM_ADDR + "00000001";
      wait for 50 ns;
  end loop;
  RAM_ADDR <= "00000000";
  RAM_WR_EN <= '1';
  RAM_OUT_EN <='0';
  -- start writing to RAM
  wait for 100 ns;
  for i in 0 to 5 loop
  RAM_ADDR <= RAM_ADDR + "00000001";
  RAM_DATA_IN_OUT <= RAM_DATA_IN_OUT-x"01";
      wait for 50 ns;
  end loop; 
  RAM_WR_EN <= '0';
  RAM_OUT_EN <='1';
  RAM_ADDR <= "00000000";
  RAM_DATA_IN_OUT <= "00000000";
  wait for 295 ns;
 
  RAM_ADDR <= "00000000";

  -- start reading data from RAM
  --for i in 0 to 5 loop
  --RAM_ADDR <= RAM_ADDR + "00000001";
  --    wait for 100 ns;
  --end loop;
 
WAIT;                                                       
END PROCESS mem_test;   


CLK : PROCESS                                               
-- variable declarations                                     
BEGIN                                                       
       -- code executes for every event on sensitivity list 
for i in 0 to 1000 loop
RAM_CLK<='0';
wait for 5 ns;
RAM_CLK<='1';
wait for 5 ns;

end loop;
WAIT;                                                       
END PROCESS CLK;                                       
                                         
END project1_arch;


after reading the generated RAM (which is initially empty), I try to write into the RAM and read the first address of the written RAM again. The result is like this :


the logic becomes floating after I try to read the RAM (red lines)...do you know what is wrong with this simulation?? :horse:
btw I am still new to FPGA and I hope you could give me guidance for this problem since I am still unable to resolve it until now..thanks before :D
« Last Edit: March 06, 2024, 09:15:35 am by e0ne199 »
 

Offline Daixiwen

  • Frequent Contributor
  • **
  • Posts: 352
  • Country: no
Re: Problems with Quartus Modelsim simulation
« Reply #1 on: March 04, 2024, 02:29:00 pm »
When reading from your test bench, you need to assign a high impedance value to RAM_DATA_IN_OUT:
Code: [Select]
  RAM_DATA_IN_OUT <= (others => 'Z');
In your code currently both the test bench and the RAM try to send an output on the same signal. As long as it's 0 there won't be a problem, but if the RAM tries to assign a 1 to a signal and the test bench tries to assign a 0 to it, then there is a conflict and the resolved signal becomes 'X'.

As a side note you should avoid using ieee.std_logic_unsigned. It is non standard but unfortunately there are still a lot of examples and books that use it. It makes it also impossible to use signed signals in the same code. You should use ieee.numeric_std instead and the standard signed and unsigned types.
 

Offline e0ne199Topic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: id
Re: Problems with Quartus Modelsim simulation
« Reply #2 on: March 04, 2024, 05:31:29 pm »
When reading from your test bench, you need to assign a high impedance value to RAM_DATA_IN_OUT:
Code: [Select]
  RAM_DATA_IN_OUT <= (others => 'Z');
In your code currently both the test bench and the RAM try to send an output on the same signal. As long as it's 0 there won't be a problem, but if the RAM tries to assign a 1 to a signal and the test bench tries to assign a 0 to it, then there is a conflict and the resolved signal becomes 'X'.

As a side note you should avoid using ieee.std_logic_unsigned. It is non standard but unfortunately there are still a lot of examples and books that use it. It makes it also impossible to use signed signals in the same code. You should use ieee.numeric_std instead and the standard signed and unsigned types.

damn you are right...thank you so much for the help  ;D ;D ;D
however, do I have to change the variable if I change ieee.std_logic_unsigned into ieee.numeric_std?
 

Offline Daixiwen

  • Frequent Contributor
  • **
  • Posts: 352
  • Country: no
Re: Problems with Quartus Modelsim simulation
« Reply #3 on: March 06, 2024, 08:59:32 am »
however, do I have to change the variable if I change ieee.std_logic_unsigned into ieee.numeric_std?
You're welcome.

Switching to ieee.numeric_std implies a few changes to your code. You can't use std_logic_vector as signed or unsigned values any more, there are two new types, called "signed" and "unsigned". You can convert to and from std_logic_vector using casting. The conv_integer() function is also called to_integer() when using a "signed" or "unsigned" parameter.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf