Forum Discussion

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

Viewing variable values in VHDL

Hi,

I am quite new to VHDL and Quartus II.

I have coded a 16x8 RAM using VHDL in Quartus but I don't know how to check it because I cannot view the array variable where the data is stored in waveform simulation.

Is there anyway I can check the contents of the array..? Maybe by other means..?

Please advice.. Thanks..

19 Replies

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

    --- Quote Start ---

    Hi,

    for the memory , I am also using the megafunction to instatiate it, without writing vhdl. It performs good, you can instantiate ROMs and RAMs (also multiport). Check the related userguide. Anyway of course you can write (and read!) data into the array!

    About SignalTap (ST) it's an Embedded Logic Analyzer, useful when your FPGA is working. It probes the device's pins, showing you what is really happening in your design. No simulation, real behaviour! And the "solution" I described before is useful to me for both simulation and verification. I followed a tutorial from altera website, the online free ones.

    hope this helps,

    C

    --- Quote End ---

    Oh.. I see.. So, I do need an FPGA chip to use it..

    Hmm.. I don't have FPGA chip.. I only have Quartus to learn VHDL with at the moment..

    Thanks anyway..
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You should be able to directly write to array. What happens to your array when Quartus later synthesizes(?) the code is that it will save the data in a register or in a memory. In the mega wizard you can auto generate vhdl-blocks that will be placed in a memory block on the fpga.

    I'm not sure I'm making any sense now, a bit tired. I'll have a quick look at your code instead.

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

    one error I found is that you switch the address:

    signal Addr : unsigned (3 downto 0);

    Addr <= (A0 & A1 & A2 & A3);

    should be

    signal Addr : unsigned (3 downto 0);

    Addr <= (A3 & A2 & A1 & A0);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I seem to be able to write to the mem in my simulation but the read does not seem to work correctly. I'll see if I can look at it tomorrow.

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

    I didn't realised that you have posted.. Thanks..

    I was too busy trying to figure out.. I think I've managed to get it work but instead of using "Data : inout std_logic_vector", i seperate it into "DataIn : in..." and "DataOut : out..."

    My guess is if I use "Data : inout", Quartus doesn't know whether that pin at that particular instance is either input or output and if I assign 2 different signals to it (1 from external input and another from internal assignment) without adding more code to latch it, it just wont work..

    However, below is the updated code and the resulted waveform.

    From the resulted waveform, i think the writing process happens at the 'next clock pulse' while the reading process happens at the 'current clock pulse'. In the waveform, at the 4th clock pulse, eventhough R_Wbar is HIGH, the data "00001111" is still written into Address "1000" because at the 8th clock pulse, "00001111" is read out from Address "1000".

    library ieee;
    use ieee.std_logic_1164.all;
    use IEEE.numeric_std.all;
    entity RAM is 
        port (     A0,A1,A2,A3    : in std_logic;
                   CS        : in std_logic;
                clk        : in std_logic;
                   R_Wbar     : in std_logic;
                   DataIn    : in std_logic_vector (7 downto 0);
                DataOut    : out std_logic_vector (7 downto 0));
    end RAM;
    Architecture version1 of RAM is
        signal Addr : unsigned (3 downto 0);
        type MEM is array (15 downto 0) of std_logic_vector (7 downto 0);    
        signal MEM_s : MEM;
        
    Begin
        Addr <= (A0 & A1 & A2 & A3);
        
        Process    (clk)
        
            variable Addr_int : integer;
        
        Begin
            if Rising_Edge(clk) then
                Addr_int := TO_INTEGER(Addr);
                if (CS = '0') then
            
                    if (R_Wbar = '0') then 
                        MEM_s(Addr_int) <= DataIn;
                      elsif (R_Wbar = '1') then
                        DataOut <= MEM_s(Addr_int) ;
                    end if;
                else
                    DataOut <= "ZZZZZZZZ";
                end if;
            end if;
        End process;
    End version1;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    A detailed explaination of FPGA internal RAM timing can be found in the RAM Megafunction user guide. It's particularly helpful to understand the available option when infering Megafunction from HDL, as you did in your example.

    It should be also possible to operate your RAM example with a bidirectional data port. The bidirectional IO cells have separate in- and output port at the FPGA side, all you need is an output enable signal with correct timing. This implies for synchronous solution, that the inout port must been set to 'Z' (= OE deasserted) one clock cycle before the input data can be latched. Alternatively, OE can be operated asynchronously from RW signal.

    P.S.: As you already find out, the Quartus integrated simulator isn't able to display RAM cell internal data. This can be done very comfortable with ModelSIm. The Megafunction user guide shows also ModelSim simulation examples.

    It isn't generally necessary to invert your address bit direction to

    Addr <= (A3 & A2 & A1 & A0);

    as suggested cause the same permutation is in effect for read and write, but the reversed bit order may cause confusion when analyzing simulation results with interger addresses.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It should be also possible to operate your RAM example with a bidirectional data port. The bidirectional IO cells have separate in- and output port at the FPGA side, all you need is an output enable signal with correct timing. This implies for synchronous solution, that the inout port must been set to 'Z' (= OE deasserted) one clock cycle before the input data can be latched. Alternatively, OE can be operated asynchronously from RW signal.

    --- Quote End ---

    Thanks..

    Umm, I don't quite get it on the OE and RW part especially "OE can be operated asynchronously from RW signal".. Is OE different from RW..?

    Can you please advice how I can convert the code in Post# 16 (using seperate DataIn and DataOut port) into a code that is using bidirectional port..?

    Maybe, can you modify the existing code from Post# 16 as an example..? I understand better from examples..

    Thanks and thanks again..
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    P.S.: As you already find out, the Quartus integrated simulator isn't able to display RAM cell internal data. This can be done very comfortable with ModelSIm. The Megafunction user guide shows also ModelSim simulation examples.

    --- Quote End ---

    I found http://www.altera.com/literature/ug/ug_ram.pdf. I am not sure if thats what u were refering to. However, its in Verilog. Do U know of any one in VHDL..?

    Thanks..

    By the way, in that example, they have "rden" and "wren" instead of just "RW" and they have a seperate output port "q". Is there any difference is using bidirectional port..?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I wasn't aware of anything specific to Verilog in ug_ram.pdf. If it's the case with instantiation examples, they can be done with VHDL as well. To my opinion, the equivalence of Verilog and VHDL should be almost obvious. RAM inference from VHDL code is also discussed in the "book", the complete Quartus II handbook.

    With oe, I meant the output enable port of IO cells, that comes into play with bidirectional or threestate outputs. It exists in the synthesized logic, although it's not a signal in your code. It's helpful to my opinion, to consider that your logic must be able to drive an output enable and what should be it's timing.

    I didn't exactly understand what's the purpose of your RAM design. Due to the synchronous nature of FPGA internal RAM, particularly the registered input signals, you can't model an asynchronous RAM this way. An appropriate design depends on the timing of the external bus. I have examples, where an internal RAM is connected to an asynchronous processor bus. But a bus cycle has a duration of serveral FPGA clocks in this case. I'm using explicite altsyncram instances rather than inference from VHDL, cause I need additional features as dual port with different word widths that can't be inferred from HDL.