Memory Types
- Asynchronous memory
Use Look-Up Tables - We do not recommend to use it for the large memory implementation
- Synchronous memory
- Register input address
- Register output data
- Register both input address and output data
Use Block Memory. Notes:
- Registering either input or output results in a one-clock-cycle delay.
- Registering both input and output results in a two-clock-cycle delay.
- Tested in Altera Quartus II. Some codes below may use Look-Up Tables in Xilinx.
Asynchronous Memory
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module async_single_port_ram(
input [6:0] data,
input [12:0] addr,
input we, clk,
output [6:0] q);
reg [6:0] ram[0:4799];
always @ (posedge clk)
begin
if (we)
ram[addr] <= data;
end
assign q = ram[addr]; // read with input address directly
endmodule
|
Synchronous Memory - Register Input - Single port
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
module sync_single_port_ram_input_reg( input [6:0] data, input [12:0] addr, input we, clk, output [6:0] q); reg [6:0] ram[0:4799]; reg [12:0] addr_reg; always @ (posedge clk) begin if (we) ram[addr] <= data; addr_reg <= addr; // register address - input end assign q = ram[addr_reg]; // read with registered address endmodule |
Synchronous Memory - Register Output - Single port
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module sync_single_port_ram_output_reg(
input [6:0] data,
input [12:0] addr,
input we, clk,
output reg [6:0] q);
reg [6:0] ram[0:4799];
always @ (posedge clk)
begin
if (we)
ram[addr] <= data;
q <= ram[addr]; // register output data - output
end
endmodule
|
Synchronous Memory - Register Input and Output - Single port, Single-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
module sync_single_port_ram_single_clock_input_output_reg( input [6:0] data, input [12:0] addr, input we, clk, output reg [6:0] q); reg [6:0] ram[0:4799]; reg [12:0] addr_reg; always @ (posedge clk) begin if (we) ram[addr] <= data; addr_reg <= addr; // register address - input q <= ram[addr_reg]; // register output data - output end endmodule |
Synchronous Memory - Register Input and Output - Single port, Dual-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
module sync_single_port_ram_dual_clock_input_output_reg( input [6:0] data, input [12:0] addr, input we, in_clk, out_clk, output reg [6:0] q); reg [6:0] ram[0:4799]; reg [12:0] addr_reg; always @ (posedge in_clk) begin if (we) ram[addr] <= data; addr_reg <= addr; // register address - input end always @ (posedge out_clk) q <= ram[addr_reg]; // register output data - output endmodule |
Synchronous Memory - Register Input - Simple Dual Port Memory - Single-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
module sync_simple_dual_port_ram_single_clock_input_reg( input [6:0] data, input [12:0] read_addr, write_addr, // two addresses input we, clk, output [6:0] q); reg [6:0] ram[0:4799]; reg [12:0] read_addr_reg; always @ (posedge clk) begin if (we) ram[write_addr] <= data; read_addr_reg <= read_addr; // register input end assign q = ram[read_addr_reg]; // read with registered address endmodule |
Synchronous Memory - Register Output - Simple Dual Port Memory - Single-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module sync_simple_dual_port_ram_single_clock_output_reg( input [6:0] data, input [12:0] read_addr, write_addr, // two addresses input we, clk, output reg [6:0] q); reg [6:0] ram[0:4799]; always @ (posedge clk) begin if (we) ram[write_addr] <= data; q <= ram[read_addr]; // register output end endmodule |
Synchronous Memory - Register Input - Simple Dual Port Memory - Dual-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
module sync_simple_dual_port_ram_dual_clock_input_reg( input [6:0] data, input [12:0] read_addr, write_addr, // two addresses input we, read_clock, write_clock, // two clocks output [6:0] q); reg [6:0] ram[0:4799]; reg [12:0] read_addr_reg; always @ (posedge write_clock) // write clock begin if (we) ram[write_addr] <= data; end always @ (posedge read_clock) // read clock begin read_addr_reg <= read_addr; // register input end assign q = ram[read_addr_reg]; // read with registered address endmodule |
Synchronous Memory - Register Output - Simple Dual Port Memory - Dual-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
module sync_simple_dual_port_ram_dual_clock_output_reg( input [6:0] data, input [12:0] read_addr, write_addr, // two addresses input we, read_clock, write_clock, // two clocks output reg [6:0] q); reg [6:0] ram[0:4799]; always @ (posedge write_clock) // write clock begin if (we) ram[write_addr] <= data; end always @ (posedge read_clock) // read clock begin q <= ram[read_addr]; // register output end endmodule |
Synchronous Memory - Register Output - True Dual Port Memory - Single-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
module sync_true_dual_port_ram_single_clock_output_reg( input [6:0] data_a, data_b, input [12:0] addr_a, addr_b, input we_a, we_b, clk, output reg [6:0] q_a, q_b); reg [6:0] ram[0:4799]; always @ (posedge clk) // port a, single-clock if (we_a) begin ram[addr_a] <= data_a; q_a <= data_a; end else q_a <= ram[addr_a]; always @ (posedge clk) // port b, single-clock if (we_b) begin ram[addr_b] <= data_b; q_b <= data_b; end else q_b <= ram[addr_b]; endmodule |
Synchronous Memory - Register Output - True Dual Port Memory - Dual-Clock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
module sync_true_dual_port_ram_dual_clock_output_reg( input [6:0] data_a, data_b, input [12:0] addr_a, addr_b, input we_a, we_b, clk_a, clk_b, output reg [6:0] q_a, q_b); reg [6:0] ram[0:4799]; always @ (posedge clk_a) // port a, dual-clock if (we_a) begin ram[addr_a] <= data_a; q_a <= data_a; end else q_a <= ram[addr_a]; always @ (posedge clk_b) // port b, dual-clock if (we_b) begin ram[addr_b] <= data_b; q_b <= data_b; end else q_b <= ram[addr_b]; endmodule |
Exercise
Try to design
- Synchronous Memory - Register Input - True Dual Port Memory - Single-Clock
- Synchronous Memory - Register Input - True Dual Port Memory - Dual-Clock
- Synchronous Memory - Register Input and Output for all the combinations of
- simple dual port and true dual port
- single-clock and dual-clock
- Prepare test bench for each implementation and simulate it with ModelSim