Verilog没有葵花宝典——day13(存储器)

题目

  1. 存储名词解释
  2. 用verilog实现一个深度为16,位宽8bit的单端口SRAM。搭建一个仿真环境,完成初始化,读取,写入的操作。
  3. 接第2题,如果同时对一个地址进行读和写操作,会怎样?实际中应该如何处理?
  4. 使用单端口SRAM构造一个双端口同步FIFO。

1. 存储名词解释

Verilog99题的第31题

2. 单端口SRAM

Verilog描述

module spram
#(
    parameter WD = 8,       //数据位宽
    parameter AD = 4       //地址位宽
)
(
    input               clk     ,
    input               cs_n    ,
    input               w_r_n   ,
    input       [AD-1:0]  addr    ,
    input       [WD-1:0]  din     ,
    output  reg [WD-1:0]  dout    
    );
localparam	DP=1<<AD;
reg [WD-1:0]  buffer  [DP-1:0];

always @(posedge clk) begin
    casex ({cs_n,w_r_n})
        2'b1x: dout <= 'hx;
        2'b01: buffer[addr] <= din;
        2'b00: dout <= buffer[addr];
        default: ;
    endcase
end

endmodule

testbench

`timescale 1ns / 1ps

// memory inst hierachy name
`define MEM_INST      tb34.spram16_8.buffer
// memory initilazation file (hex format)
`define MEM_INIT_FILE "E:/verilog/test/test.srcs/sources_1/new/sp_mem_init.hex"

module tb34(    );
reg             clk     ;
reg             cs_n    ;
reg             w_r_n   ;
reg     [4:1]   addr    ;
reg     [8:1]   din     ;
wire    [8:1]   dout    ;

initial begin
    clk = 1;
    forever #10 clk = ~clk;
  end

// memory initilization
integer fp_dmem;

initial begin
    fp_dmem = $fopen(`MEM_INIT_FILE, "r");  //open for read
    if(fp_dmem)
        #5 $readmemh(`MEM_INIT_FILE, `MEM_INST);
    else begin
        $display("%s open failed.",`MEM_INIT_FILE);
        $finish;
    end
end

integer i;
initial begin
    cs_n = 1'b1;
    w_r_n = 1'b0;
    addr = 4'd0;
    din = 8'h00;
    #100
    @(negedge clk)//read
        cs_n = 1'b0;
    for (i = 0; i<16; i=i+1) begin
        @(negedge clk)
            addr = i;
    end
    @(negedge clk)//write
        w_r_n = 1'b1;
    for (i = 0; i<16; i=i+1) begin
        @(negedge clk) begin
            addr = i;
            din = i + 'ha0;
        end
    end
    @(negedge clk)//read
        w_r_n = 1'b0;
    for (i = 0; i<16; i=i+1) begin
        @(negedge clk)
            addr = i;
    end
    @(negedge clk)
        cs_n = 1'b1;
    // #100 $finish;
    #100 $stop;
end

/* initial begin
    $dumpfile("spram_tb.vcd");
    $dumpvars();
end */
spram #(
    .WD ( 8),
    .AD ( 4)
)
spram16_8
(
    .clk     ( clk   ),
    .cs_n    ( cs_n  ),
    .w_r_n   ( w_r_n ),
    .addr    ( addr  ),
    .din     ( din   ),
    .dout    ( dout  )
    );
endmodule

3. 接第2题,如果同时对一个地址进行读和写操作,会怎样?实际中应该如何处理?

目前的水平觉得不会,但是大神们讨论了很多,不敢说话。

4. 使用单端口SRAM构造一个双端口同步FIFO。

放出大神的思路使用单端口SRAM构造一个双端口同步FIFO

只想说厉害了!说得比较通俗易懂,实现起来没那么简单~

估计今天是实现不了了,留坑!

即将入行的数字IC设计工程师