Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16613 Discussions

Viewing variable values in VHDL

Altera_Forum
Honored Contributor II
4,405 Views

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..
0 Kudos
19 Replies
Altera_Forum
Honored Contributor II
2,547 Views

What simulation tool are you using? In most simulation programs you can set which format you want to view data in, an array can be handy to show in hex for example. 

 

//Ola
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

Thanks for the reply.. 

 

I am using Functional Simulation. I have heard of testbenches but don't really know how to use it..  

 

What I hope to achieve is to be able to know what data is actually written into and stored in the array when data is written through the Data pins (declared as "inout std_logic_vector (7 downto 0)") during the writing process and, to be able to view the data output through the Data pins during reading process.
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

Your problems sounds quite simple, there must be an easy way to display arrays, but since I've never used the altera simulation I can't help you there.  

 

I've looked around here on the forum before and people tend to think that modelsim has many advantages. If you like I can send you a design file with corresponding test bench and a do file. Just reply with your email. What you then is to start a modelsim project, compile the file and write "do <file.do>". Very simple. 

 

//Ola
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

Yes please.. 

I've already PMed u the email.. 

Thanks..
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

Hi mrnobody, 

I don't know if I understood well your problem, anyway seems similiar to what I had: I wanted to "check" internal signals with a Vector Waveform File.  

Now I do this: simply define a extra output port in my entity, and connect it to the signal I wanted to do. This is useful also when I use SignalTap analyzer. For example (just the shortest piece of VHDL code, if needed I can post more): 

 

romprobe <= romout ; -- STII / VWF signal 

 

where romout is the "real" output of my ROM, and romprobe is the "extra" port as described above. 

 

hope this helps, 

 

C
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

Well.. 

 

Below is the RAM code that I've done in VHDL. 

 

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; Data : inout std_logic_vector (7 downto 0); DataOut : out std_logic_vector (7 downto 0)); -- for testing 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) <= Data; DataOut <= MEM_s(Addr_int); elsif (R_Wbar = '1') then Data <= MEM_s(Addr_int) ; DataOut <= Data; end if; end if; end if; End process; End version1;  

What I set in waveform simulator before the simulation is shown in BeforeSim.jpg attached below. 

 

The result of the simulation is shown in AfterSim.jpg also attached below. 

 

In the first clock pulse, the address of the RAM (A0 to A3) is all 0. 

I manually set the Data pin (of the RAM) to 1. Since this is the writing process (because R_Wbad is 0, I was hoping to get "11111111" in the DataOut pin (output pin to display the array values). However, I got "00000000" instead. 

 

In the following clock pulse (supposed to be the reading cycle to read the information in the array), the Data pin (of the RAM) is at high impedance state. What I hope to get is the value for Data and DataOut to both be "11111111" because "11111111" is written in the first clock pulse. 

 

If this is C#, my next action would be to use the built in debugger to try to figure out what went wrong. However, since I am new to VHDL, I am totally lost.. I am not even sure if the data is actually written into the RAM's array. 

 

Please advice.. 

Thanks..
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

Bango:  

I've downloaded ModelSim and tried it. It seems similar to the waveform simulator in Quartus i guess. 

 

cirutech: 

I've only tried Vector Waveform File simulator in Quartus. However, I am very keen in learning how to use SignalTap if that can help me in learning VHDL. Do you know of a good tutorial that I can follow..? Preferably one that explains by example.. 

Thanks..
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

In the megawizard you can instantiate ram blocks so you don't need to write them yourself. Try that, could be something in the code.  

 

//Ola
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

 

--- Quote Start ---  

In the megawizard you can instantiate ram blocks so you don't need to write them yourself. Try that, could be something in the code.  

 

//Ola 

--- Quote End ---  

 

Instantiate ram blocks..? 

You mean the array "MEM" need to be instantiated..? (Whatever that means..).. U mean, I cannot directly write data into the array..? 

I didn't know that..  

Ok.. i'll try to find some info about instantiating array in google..  

 

Thanks.. 

 

Oh.. by the way, does the code's logic seems ok to you..? Apart from the instantiating thingy, is there anything wrong with the code..? I spent few hours trying to write this code and i am not even sure if it is ok.. As for compiling it, there is not error tho..
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

 

--- Quote Start ---  

Instantiate ram blocks..? 

You mean the array "MEM" need to be instantiated..? (Whatever that means..).. U mean, I cannot directly write data into the array..? 

<snip> 

cirutech: 

I've only tried Vector Waveform File simulator in Quartus. However, I am very keen in learning how to use SignalTap if that can help me in learning VHDL. Do you know of a good tutorial that I can follow..? Preferably one that explains by example.. 

--- Quote End ---  

 

 

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
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

 

--- 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, 

 

--- 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..
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

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);
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

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;
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

 

--- 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..
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

 

--- 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..?
0 Kudos
Altera_Forum
Honored Contributor II
2,547 Views

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.
0 Kudos
Reply