본문 바로가기
Digital Design/컴퓨터구조

[메모리] SRAM에 데이터 쓰고 읽기 (Design with Verilog)

by 스테고사우르스 2023. 1. 8.

이전 글에서 SRAM을 Full Custom Design 했었습니다.

 

이제 메모리가 만들어졌다고 가정하고,

데이터를 읽고 쓰는 과정을 진행해보겠습니다.

 

 


Verilog Code

 

DUT

`timescale 1ns / 1ps

module sync_sram(addr, din, dout, clk, we);

parameter addr_width = 8, word_depth = 256, word_width = 8;

input clk, we;
input [addr_width-1:0] addr;
input [word_width-1:0] din;
output reg [word_width-1:0] dout;

reg [word_width-1:0] mem [0:word_depth-1];

always @ (posedge clk) begin
    if(!we)
        mem[addr] <= din[word_width-1:0];
end

always @ (posedge clk) begin
    #1 dout <= mem[addr];
end

endmodule

 

we는 write enable로 Read와 Write를 결정합니다.

 

여기서 두 번째 always block을 보면 #1이 있는데,

1ns delay시키는 구문입니다.

 

회로에는 항상 Delay가 존재합니다.

 

하지만 Register Transfer Level에서는 delay를 무시하고 시뮬레이션을 합니다.

 

따라서 대충 1ns 정도 delay 된다고 가정하고 delay된 결과를 보기 위해 #1을 사용하였습니다.

 

대신 이건 시뮬레이션을 위해 작성한것으로 이대로 합성하면 절대 안됩니다!

 

 

Testbench

`timescale 1ns / 1ps

module tb_sync_sram();

parameter addr_width = 8, word_depth = 256, word_width = 8;

reg clk, we;
reg [addr_width-1:0] addr;
reg [word_width-1:0] din;
wire [word_width-1:0] dout;

sync_sram sram01(addr, din, dout, clk, we);

always #5 clk = ~clk;
initial begin
    clk = 1'b0; addr[addr_width-1:0] = 0; din[word_width-1:0] = 8'b10000000; we = 1'b0; #10
    addr[addr_width-1:0] = 1; din[word_width-1:0] = 8'b10000001; #10
    addr[addr_width-1:0] = 2; din[word_width-1:0] = 8'b10000010; #10
    addr[addr_width-1:0] = 3; din[word_width-1:0] = 8'b10000011; #10
    addr[addr_width-1:0] = 4; din[word_width-1:0] = 8'b10000100; #10
    addr[addr_width-1:0] = 5; din[word_width-1:0] = 8'b10000101; #10
    addr[addr_width-1:0] = 6; din[word_width-1:0] = 8'b10000110; #10
    addr[addr_width-1:0] = 7; din[word_width-1:0] = 8'b10000111; #10
    addr[addr_width-1:0] = 8; din[word_width-1:0] = 8'b10001000; #10
    addr[addr_width-1:0] = 9; din[word_width-1:0] = 8'b10001001; #10
    addr[addr_width-1:0] = 10; din[word_width-1:0] = 8'b10001010; #10
    addr[addr_width-1:0] = 11; din[word_width-1:0] = 8'b10001011; #10
    addr[addr_width-1:0] = 12; din[word_width-1:0] = 8'b10001100; #10
    addr[addr_width-1:0] = 13; din[word_width-1:0] = 8'b10001101; #10
    addr[addr_width-1:0] = 14; din[word_width-1:0] = 8'b10001110; #10
    addr[addr_width-1:0] = 15; din[word_width-1:0] = 8'b10001111; #10
    we = 1'b1; addr[addr_width-1:0] = 0; #10
    addr[addr_width-1:0] = 1; #10
    addr[addr_width-1:0] = 2; #10
    addr[addr_width-1:0] = 3; #10
    addr[addr_width-1:0] = 4; #10
    addr[addr_width-1:0] = 5; #10
    addr[addr_width-1:0] = 6; #10
    addr[addr_width-1:0] = 7; #10
    addr[addr_width-1:0] = 8; #10
    addr[addr_width-1:0] = 9; #10
    addr[addr_width-1:0] = 10; #10
    addr[addr_width-1:0] = 11; #10
    addr[addr_width-1:0] = 12; #10
    addr[addr_width-1:0] = 13; #10
    addr[addr_width-1:0] = 14; #10
    addr[addr_width-1:0] = 15; #10
    $finish;
end

endmodule

 

Simulation

 

 


 

댓글