FONT SIZE : AAA
A dynamic random access memory (RAM) block has a two-dimensional structure of memory that is divided into a grid structure that can be accessed by a row address and column address (obviously this is one way of carrying this out, but it is often the approach required for dynamic RAM). Note that this is asynchronous and therefore has no clock. The implication of being asynchronous is that great care must be taken with the timing of the memory access to ensure data integrity throughout the transfer process.
The VHDL model has a single address input and two control signals row and col used to load the row and column address, respectively. There is also a rw signal that is defined as being write when high and read when low. Finally, the data is put onto the data signal, which is defined as an inout (bidirectional) signal. The resulting model is given in the VHDL following. In this example, the number of rows is 28 and the number of columns also 28. This gives a total data storage with 16 bits of 1 MBit.
1 library ieee;
2 use ieee.std_logic_1164.all; 3 use ieee.numeric_std.all; 45 entity dram1mb is
6 port ( 7 address : in integer range 0 to 2∗∗8−1; −− Row Address
8 row : in std_logic; −− Row Select
9 col : in std_logic; −− Column Select
10 rw : std_logic; −− Read/Write
11 data : inout std_logic_vector (15 downto 0) −− Data
12 );
13 end entity dram1mb;
14
15 architecture behav of dram1mb is
16 begin
17 process (row, col, rw) is
18 type dram is array (0 to 2∗∗16 − 1) of std_logic_vector(15 downto 0);
19 variable radd: INTEGER range 0 to 2∗∗8 − 1;
20 variable madd: INTEGER range 0 to 2∗∗16 − 1;
21 variable memory: dram;
22 begin
23 data <= (others => ’Z’);
24 if falling_edge(row) then
25 radd := address;
26 elsif falling_edge(col) then
27 madd :=radd∗2∗∗8 +address;
28 if row = ’0’ and rw = ’0’ then
29 memory(madd) := data;
30 end if;
31 elsif col = ’0’ and row = ’0’ and rw = ’1’ then
32 data <= memory(madd);
33 end if;
34 end process;
35 end architecture behav;
Using this model a simple testbench can be used to read in a data value to an address, then another value to another address and then the original value read back. The test bench to achieve this is given in the VHDL.
1 library ieee;
2 use ieee.std_logic_1164.all; 34 entity testram is
5 end entity testram;
67 architecture test of testram is
8 signal address : integer range 0 to 2∗∗8−1 := 0;
9 signal rw : std_logic;
10 signal c : std_logic;
11 signal r : std_logic;
12 signal data : std_logic_vector ( 15 downto 0 );
13 begin
14
15 dram: entity work.dram1mb(behav)
16 port map ( address, r, c, rw, data );
17 address <= 23 after 0 ns, 47 after 30 ns, 23 after 90 ns;
18 rw <= ’0’ after 0 ns, ’1’ after 90 ns;
19 c <= ’1’ after 0 ns, ’0’ after 20 ns,
20 ’1’ after 50 ns, ’0’ after 70 ns,
21 ’1’ after 90 ns, ’0’ after 100 ns;
22 r <= ’1’ after 0 ns, ’0’ after 10 ns,
23 ’1’ after 40 ns, ’0’ after 60 ns,
24 ’1’ after 80 ns, ’0’ after 100 ns;
25 data <= X"1234" after 0 ns, X"5678" after 40 ns;
26
27 end architecture test;
The results of testing this model can be seen in the waveform plot in Figure 11.1, which shows the correct behavior of the address, data, and control lines.
The Verilog model has a single address input and two control signals row and col used to load the row and column address, respectively. There is also a rw signal that is defined as being write when high and read when low. Finally, the data is put onto the datain signal, which is defined as an input signal and read back from the dataout signal which is defined as a register. The resulting model is given in the Verilog following. In this example, the number of rows is 28 and the number of columns also 28. This gives a total data storage with 16 bits of 1 MBit.
1 module dram1mb ( address, row, col, rw, datain, dataout );
23 input [7:0] address; / Address
4 input row; / Row Selector
5 input col; / Column Selector
6 input rw; / Read/Write
7 input [15:0] datain ; / Data In
8 output [15:0] dataout ; / Data Out
9
10 wire [15:0] datain;
11 reg [15:0] dataout ; / Data defined as a register
12
13 reg [7:0] radd; / Row Address
14 reg [15:0] madd; / Overall memory Address
15
16 / define the memory array
17 reg [15:0] memory [0:255]; / the memory array is 16 bits wide (data) and
2∗∗8 −1 deep (address)
18
19 always @ (negedge row)
20 begin
Figure 11.1
Basic VHDL RAM simulation.
21 radd = address;
22 end
23
24 always @ (negedge col)
25 begin
26 madd = radd∗2∗∗8 + address;
27 if(!rw) begin
28 memory[madd] <= datain;
29 end
30 else begin
31 dataout <= memory[madd];
32 end
33 end
34 endmodule
Using this model, a simple testbench can be used to read in a data value to an address, then another value to another address and then the original value read back. The test bench to achieve this is given in the Verilog following. Note as stated earlier that this is an asynchronous model, which means that the rw signal must be defined prior to the col control signal going low (and it is very important to not make this coincident with the rw signal, otherwise a race condition would arise).
12 module dram1mb_tb();
3 / declare the counter signals
4 reg row;
5 reg col;
6 reg rw;
7 reg [7:0] address;
8 wire [15:0] dataout;
9
10 reg [15:0] datain;
11
12 / Set up the initial variables and reset
13 initial begin
14 $display ("time\t row col rw address data data_set");
15 $monitor ("%g\t %b %b %b %d %d %d",
16 $time, row, col, rw, address, datain, dataout);
17 row = 1; / initialize the row to 1
18 col = 1; / set the col to 1
19 rw = 1; / set the rw to 1
20
21 #1 address = 0; / set the row to 1
22 #1 datain = 23;
23 #1 row = 0; / set the row to 0
24 #1 row = 1; / set the row to 1
25 #1 address = 1; / set the row to 1
26 #1 rw = 0; / set the rw to 0
27 #1 col = 0; / set the col to 0
28 #1 col = 1; / set the col to 1
29 #1 rw = 1; / set the rw to 1
30
31 / This should have written the data of 23 into location 0:1
32
33
34 #1 address = 0; / set the row to 1
35 #1 datain = 47; / set the data to 47
36 #1 row = 0; / set the row to 0
37 #1 row = 1; / set the row to 1
38 #1 address = 2; / set the row to 2
39 #1 rw = 0; / set the rw to 0
40 #1 col = 0; / set the col to 0
41 #1 col = 1; / set the col to 1
42 #1 rw = 1; / set the rw to 1
43
44 / This should have written the data of 47 into location 0:2
45
46 #1 address = 0; / set the row to 1
47 #1 row = 0; / set the row to 0
48 #1 row = 1; / set the row to 1
49 #1 address = 1; / set the row to 1
50 #1 col = 0; / set the col to 0
51 #1 col = 1; / set the col to 1
52
53 #100 $finish; / Finish the simulation
54 end
55
56 dram1mb RAM ( address, row, col, rw, datain, dataout);
57
58 endmodule
The results of testing this model can be seen in the waveform plot in Figure 11.2 which shows the correct behavior of the address, data, and control lines.
This model is different from the VHDL in an important aspect: that the memory has a separate data input and output port (defined as an input and output, respectively). This is not what was defined in the VHDL model, which used a single inout port for the data. Therefore, how can this be done using Verilog? We have two basic types in verilog, wire for direct connections and reg for registers. If we use an inout type for the port, then a register cannot be used, but also a wire does not hold the value, so how can we reconcile this in a RAM model? The answer is to declare an internal register to hold the output value of the data port, and then, depending on the value of the rw command signal, define the data port as having the value defined by the output register (in this model dataout) or making it a high impedance state (tri-state). This port can then be driven externally, as is shown in the test bench.
Figure 11.2
Basic Verilog RAM simulation.
1 module dram1mbio ( address, row, col, rw, data );
2 input [7:0] address; / Address
3 input row; / Row Selector
4 input col; / Column Selector
5 input rw; / Read/Write
6 inout [15:0] data ; / Data In
78 wire [15:0] data;
9 reg [15:0] dataout ; / Data defined as a register
10
11 reg [7:0] radd; / Row Address
12 reg [15:0] madd; / Overall memory Address
13
14 / define the memory array
15 reg [15:0] memory [0:255]; / the memory array is 16 bits wide (data) and
2∗∗8 −1 deep (address)
16 assign data = (rw) ? dataout : 16’hz;
17 always @ (negedge row)
18 begin
19 radd = address;
20 end
21
22 always @ (negedge col)
23 begin
24 madd = radd∗2∗∗8 + address;
25 if(!rw) begin
26 memory[madd] <= data;
27 end
28 else begin
29 dataout <= memory[madd];
30 end
31 end
32 endmodule
Using this model a simple testbench can be used to read in a data value to an address, then another value to another address, and then the original value read back. The test bench to achieve this is given in the Verilog following. Note as stated earlier that this is an asynchronous model, which means that the rw signal must be defined prior to the col control signal going low (and it is very important to not make this coincident with the rw signal, otherwise a race condition would arise). In the test bench, it can be seen that the same tri-state technique is required as in the RAM model itself, allowing the single port to be used as an input to read the data into the memory or as a register to write the requested data value back out to the data bus.
12 module dram1mbio_tb();
3 / declare the counter signals
4 reg row;
5 reg col;
6 reg rw;
7 reg [7:0] address;
8 wire [15:0] data;
9
10 reg [15:0] datain;
11
12 assign data = (!rw) ? datain : 16’hz;
13
14 / Set up the initial variables and reset
15 initial begin
16 $display ("time\t row col rw address data data_set");
17 $monitor ("%g\t %b %b %b %d %d %d",
18 $time, row, col, rw, address, datain, data);
19 col = 1; / set the col to 1
20 rw = 1; / set the rw to 1
21
22 #1 address = 0; / set the row to 1
23 #1 datain = 23;
24 #1 row = 0; / set the row to 0
25 #1 row = 1; / set the row to 1
26 #1 address = 1; / set the row to 1
27 #1 rw = 0; / set the rw to 0
28 #1 col = 0; / set the col to 0
29 #1 col = 1; / set the col to 1
30 #1 rw = 1; / set the rw to 1
31
32 / This should have written the data of 23 into location 0:1
33
34
35 #1 address = 0; / set the row to 1
36 #1 datain = 47; / set the data to 47
37 #1 row = 0; / set the row to 0
38 #1 row = 1; / set the row to 1
39 #1 address = 2; / set the row to 2
40 #1 rw = 0; / set the rw to 0
41 #1 col = 0; / set the col to 0
42 #1 col = 1; / set the col to 1
43 #1 rw = 1; / set the rw to 1
44
45 / This should have written the data of 47 into location 0:2
46
47 #1 address = 0; / set the row to 1
48 #1 row = 0; / set the row to 0
49 #1 row = 1; / set the row to 1
50 #1 address = 1; / set the row to 1
51 #1 col = 0; / set the col to 0
52 #1 col = 1; / set the col to 1
53
54 #100 $finish; / Finish the simulation
55 end
Figure 11.3
Basic RAM simulation with a common data port.
56
57 dram1mbio RAM ( address, row, col, rw, data);
58
59 endmodule
The results of testing this model can be seen in the waveform plot in Figure 11.3 which shows the correct behavior of the address, data, and control lines.
It is important to note that the RAM model in both VHDL and Verilog cases does not model any of the actual delays that would appear in practice and if this is important to the functionality of the design, then it MUST be added to the model. Also, note that this could be obtained from a data sheet for DRAM (dynamic RAM); however, the delays would have an uncertainty attached to them.
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: -
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: No RoHS
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: No RoHS
Manufacturer:Xilinx
Product Categories: FPGAs
Lifecycle:Obsolete -
RoHS:
Manufacturer:Xilinx
Product Categories: Condensateurs électrolytiques en aluminium
Lifecycle:Obsolete -
RoHS:
Support