SRAM
SRAM (Static random-access memory)
데이터는 플립플랍(레지스터)에도 저장할 수 있지만, 저장해야 할 데이터의 크기가 커지면 SRAM에 저장하는 게 더 나을 수 있습니다. SRAM은 같은 크기의 데이터를 저장할 때 flip-flop에 비해 더 적은 트랜지스터를 사용하거든요. 그렇다고 무조건 SRAM을 사용하는 게 좋은 건 아닙니다. SRAM을 사용하기 위해서는 ampliefier, driver 등의 회로가 추가적으로 필요하므로, 저장해야 할 데이터의 크기가 작다면 flip-flop을 사용하는 게 area가 더 작을 수도 있습니다. 여하튼 상황에 따라 적절하게 flip-flop 또는 sram을 사용합니다.
SRAM은 Static Random-access Memory의 줄임말입니다. 각 뜻을 살펴보면,
- Static : 값이 변하지 않고 일정하게 유지된다는 뜻입니다. Dynamic Ram(DRAM)과 같은 다른 종류의 메모리는 가만히 두면 값을 잃어버리는 경우도 있어서, 주기적으로 값을 refresh 해줘야 하는 경우도 있어요. 이에 반해 SRAM은 전원이 유지되는 한 값이 일정하게 유지됩니다.
- Random-access : 임의의 주소에 접근하는데 걸리는 시간이 동일하다는 뜻입니다. 임의의 주소에 접근하는데 걸리는 시간이 다른 저장 장치들도 있습니다. 예를 들어 하드디스크의 경우, 데이터를 읽기 위해 헤드와 플래터의 위치를 물리적으로 정렬해야 합니다. 따라서 플래터의 상태에 따라 임의의 주소에 접근하는데 걸리는 시간이 다릅니다. 이에 반해 랜덤 액세스 메모리는 임의의 주소에 접근하는 시간이 항상 동일합니다.
- Memory : 데이터를 저장할 수 있는 장치입니다.
SRAM의 크기는 width와 depth를 통해 정의됩니다. width는 한 번에 읽거나 쓰는 데이터의 크기(bit width — 8-bit, 32-bit 등)를 말하고, depth는 몇 개의 데이터를 저장할 수 있는지를 나타냅니다. width는 word size라고 말하기도 합니다.
Single-Port RAM
가장 기본적인 형태인 single-port 메모리입니다. 보통 SRAM이라고 말하면 이 경우에 해당한다고 생각하시면 됩니다. 하나의 포트를 통해 읽기/쓰기 동작을 합니다. 따라서 데이터 읽기와 쓰기를 동시에 할 수 없으므로, we
신호를 통해 읽기/쓰기 모드를 선택해서 사용합니다. 쓰기 모드에서 read_data
는 무시하면 되고, 읽기 모드에서 write_data
는 무시됩니다.
Input/Output
Name | Bit width | Description | |
---|---|---|---|
INPUT | clock | 1 | 클럭 신호입니다. |
en | 1 | enable 신호입니다. enable 상태에서만 메모리를 read 또는 write 할 수 있습니다. | |
we | 1 | write enable 신호입니다. 데이터를 저장할지, 아니면 읽을지를 선택합니다. | |
addr | M | 데이터를 쓰거나 읽을 주소를 입력합니다. | |
write_data | N | 메모리에 저장할 데이터를 입력합니다. | |
OUTPUT | read_data | N | 메모리에서 읽은 데이터가 출력됩니다. |
Verilog Code
// File: single_port_ram.v
`timescale 1ns/10ps
module single_port_ram #(
parameter ADDR_WIDTH = 6,
parameter DATA_WIDTH = 16,
parameter DEPTH = 32)
(
// input
input clk,
input en,
input we,
input [ADDR_WIDTH-1:0] addr,
input [DATA_WIDTH-1:0] write_data,
// output
output reg [DATA_WIDTH-1:0] read_data
);
// declare the RAM variable
reg [DATA_WIDTH-1:0] ram [DEPTH-1:0];
always @ (posedge clk)
begin
if (en) begin
if (we)
ram[addr] <= write_data;
else
read_data <= ram[addr];
end
end
endmodule
Waveform
- Clock cycle 3, 4, 5, 6에서 데이터를 저장합니다.
- Clock cycle 7, 8, 9, 10에서 데이터를 읽습니다.
Dual-Port RAM
위에서 본 메모리는 포트가 하나라서 동시에 Read/Write를 할 수 없었는데, 포트가 두 개인 메모리도 있습니다. 포트가 두 개라서 이름이 Dual-Port RAM입니다.
더 자세히 나누면 Simple Dual-Port RAM과 True-Dual Port RAM으로 나뉩니다.
- Simple Dual-Port RAM
- Two-Port RAM이라고도 합니다. 포트가 두 개이긴 한데 하나는 Read, 하나는 Write만 할 수 있습니다.
- True Dual-Port RAM
- 각 포트 모두 Read/Write를 할 수 있습니다. 두 개의 포트를 통해 동시에 Write를 할 수도 있고, Read를 할 수도 있어요.
아래는 Simple Dual-Port RAM에 대한 설명입니다.
Input/Output
Port A - Write Only
Name | Bit width | Description | |
---|---|---|---|
INPUT | clka | 1 | 클럭 신호입니다. |
ena | 1 | enable 신호입니다. enable 상태에서만 메모리에 write 할 수 있습니다. | |
wea | 1 | write enable 신호입니다. 데이터를 저장할지, 아니면 읽을지를 선택합니다. | |
addra | M | 데이터를 쓰거나 읽을 주소를 입력합니다. | |
write_data | N | 메모리에 저장할 데이터를 입력합니다. |
Port B - Read Only
Name | Bit width | Description | |
---|---|---|---|
INPUT | clkb | 1 | 클럭 신호입니다. |
enb | 1 | enable 신호입니다. enable 상태에서만 메모리를 read 할 수 있습니다. | |
addrb | M | 데이터를 쓰거나 읽을 주소를 입력합니다. | |
OUTPUT | read_data | N | 메모리에 저장할 데이터를 입력합니다. |
Verilog Code
// File: simple_dual_port_ram.v
`timescale 1ns/10ps
module simple_dual_port_ram #(
parameter ADDR_WIDTH = 6,
parameter DATA_WIDTH = 16,
parameter DEPTH = 32)
(
// input
input clka,
input clkb,
input ena,
input enb,
input wea,
input [ADDR_WIDTH-1:0] addra,
input [ADDR_WIDTH-1:0] addrb,
input [DATA_WIDTH-1:0] write_data,
// output
output reg [DATA_WIDTH-1:0] read_data
);
// declare the RAM variable
reg [DATA_WIDTH-1:0] ram [DEPTH-1:0];
always @(posedge clka)
begin
if (ena) begin
if (wea)
ram[addra] <= write_data;
end
end
always @(posedge clkb)
begin
if (enb) begin
read_data <= ram[addrb];
end
end
endmodule
Waveform
- Clock cycle 3, 4, 5, 6에서 데이터를 저장합니다.
- Clock cycle 3, 4, 5, 6, 7에서 데이터를 읽습니다.
- Clock cycle 3에서 저장한 값은 cycle 4에서 읽을 수 있습니다.
Leave a comment