Depends on your simulator. For Icarus, I think you need an explicit dumpvars statement for every array row you want to dump. I don't recall if you need the [msb:lsb] subscript. For CVC, you can use the +dump_arrays plusarg. I use CVC all the time and view arrays in gtkwave.
The memory is addressed using the word lines, and data is transferred into or out of the array using the bit lines.
The word lines are driven from a decoder whose input is the address bus. For any particular binary address, exactly one word line is activated. This turns on all of the pass transistors for one complete row of memory cells, connecting each pair of cross-connected inverters to its pair of bit lines. All of the other rows in the memory array are disconnected from the bit lines and do not participate in the read or write cycle.
When reading a cell, the inverters drive the bit lines — one high and one low — and circuitry not shown compares the voltages on the two bit lines and decides whether the bit is a zero or a one. The bits obtained in this way are grouped together to form a "word" of data, which is then passed to whatever external logic (CPU, video controller, or anything else) that might be connected to the data bus.
When writing a cell, another set of circuitry, also not shown, drives the bit lines — again, one high and one low for each cell. The key here is that the write driver is stronger than the inverters in the memory cell, and can impose a new state on the memory cell regardless of what its previous state might have been.
At the end of the cycle, the word line is deactivated and the cells retain their state.
Best Answer
Some tools will infer RAM. They have already thought about area, for example. See your vendor's document for details.
NC-Verilog is for functional simulation. It doesn't track area and timing. For that you need to worry about synthesis to a specific vendor's library.
Analog parts aren't supported by Verilog.