Verilog implements RAM(6-dual port asynchronous read / write SRAM)

In the previous work, we carried on the noun literacy to the common memory device, realized the simple single port synchronous read-write SRAM by calling the IP core, carried on the Verilog description to the single port synchronous read-write SRAM, carried on the design and the analysis to the single port synchronous write, asynchronous read SRAM, and the single port asynchronous read-write SRAM; and on this basis, described the dual port synchronous read-write SRAM by using Verilog Write SRAM, as shown in:

Verilog realizes RAM(5-dual port synchronous read / write SRAM)

Now, based on the previous work, further realize the dual port asynchronous read-write SRAM

I. principle

Dual port asynchronous read / write SRAM is similar to dual port synchronous read / write SRAM. The only difference is that write / read has nothing to do with clock clk, only real-time operation is performed under the control signal (such as chip selection, enable, address, etc.);

The input ports are: (asynchronous without clk)

reg [3:0]a1; / / enter the address (the RAM depth is 16, and the corresponding address bit width is 4)

reg we1;// write enable, write RAM when write enable

reg oe1;// output enable, only the result read by RAM can be output when the output is enabled

reg cs1; / / select which RAM to read

//Second set

reg [3:0]a2; / / enter the address (the RAM depth is 16, and the corresponding address bit width is 4)

reg we2;// write enable, write RAM when write enable

reg oe2;// output enable, only the result read by RAM can be output when the output is enabled

reg cs2; / / select which RAM to read

The input and output ports are:
wire [7:0]d1; / / data output when reading RAM / data input when writing RAM

wire [7:0]d2; / / data output when reading RAM / data input when writing RAM

 

Working process:

The two groups of ports perform different operations according to the value of cs/we/oe;

When cs is valid (1) and we is 1, write enable and write d input data to the corresponding address of a;

When cs is valid (1) and we is 0, reading is enabled. When oe is valid (1), data at a address is read out to d;

When dual port RAM is reading at the same time, there will be no conflict, that is, it can read the same address, and the results will be output through the respective output ports; however, when dual port RAM is writing at the same time, there may be write conflict, that is, there will be problems when dual port writes to the same address;

In order to avoid this problem, the dual port SRAM is designed as dual port synchronous read and asynchronous write; (it can read and write at the same time, but it cannot write at the same time, and only the port with high priority can be written at the same time.)

2, Code implementation:

Then, in the previous work, the Verilog description of dual port synchronous read-write SRAM is simply modified, which only needs to convert the clock excitation into clock independent - to realize a single port SRAM with a bit width of 8 bits and a depth of 16 bits;

verilog is described as follows:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: CLL
// 
// Create Date: 2020/02/25 13:38:31
// Design Name: 
// Module Name: sram_dp_araw
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module sram_dp_araw
#(parameter DW = 8,AW = 4)
(
    input [AW-1:0]a1,//address
    input cs1,// chip select
    input oe1,// output enable
    input we1,// write enable
    inout [DW-1:0]d1,// data
    // 
    input [AW-1:0]a2,//address
    input cs2,// chip select
    input oe2,// output enable
    input we2,// write enable
    inout [DW-1:0]d2// data
    );

// 
parameter DP = 1 << AW;// depth 
reg [DW-1:0]mem[0:DP-1];
reg [DW-1:0]reg_d1;
// port2
reg [DW-1:0]reg_d2;
//initialization
// synopsys_translate_off
integer i;
initial begin
    for(i=0; i < DP; i = i + 1) begin
        mem[i] = 8'h00;
    end
end
// synopsys_translate_on

// read declaration
// port1
always@(*)
begin
    if(cs1 & !we1 & oe1)
        begin
            reg_d1 = mem[a1];
        end
    else
        begin
            reg_d1 = reg_d1;
        end
end
// port2
always@(*)
begin
    if(cs2 & !we2 & oe2)
        begin
            reg_d2 = mem[a2];
        end
    else
        begin
            reg_d2 = reg_d2;
        end
end

// wrirte declaration
always@(*)
begin
    if(cs1 & we1)//port1 higher priority
        begin
            mem[a1] = d1;
        end
    else if(cs2 & we2)
        begin
            mem[a2] = d2;
        end
    else
        begin
            mem[a1] = mem[a1];
            mem[a2] = mem[a2];
        end    
end

// Three state logic
assign d1 = (cs1 & !we1 & oe1) ? reg_d1 : {DW{1'bz}};
assign d2 = (cs2 & !we2 & oe2) ? reg_d2 : {DW{1'bz}};
endmodule

Test files are similar:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: CLL
// 
// Create Date: 2020/02/24 19:25:55
// Design Name: 
// Module Name: sram_dp_srsw_tsb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module sram_dp_srsw_tsb(

    );
// port declaration
reg clk;
// port1
reg [3:0]a1;//address
reg cs1;
reg oe1;
reg we1;// write enable
wire [7:0]d1;//datain/out 
// port2
reg [3:0]a2;//address
reg cs2;
reg oe2;
reg we2;// write enable
wire [7:0]d2;//datain/out 
// reg declaration
reg [7:0]din1;
reg [7:0]din2;
// 
initial
begin
    clk = 1'b0;
    forever #10 clk = ~clk;//period = 20
end
//
assign d1 = (cs1 & we1)?din1:8'bzzzz_zzzz;
assign d2 = (cs2 & we2)?din2:8'bzzzz_zzzz;
//
initial
begin
    a1 = 4'b0000;
    din1 = 8'd1;
    we1 = 1'b0;
    oe1 = 1'b1;
    cs1 = 1'b1;
    a2 = 4'b1111;
    din2 = 8'd1;
    we2 = 1'b0;
    oe2 = 1'b1;
    cs2 = 1'b1;
    #20 / / synchronous reading, port1 reading 0-15, port2 reading 15-0
    repeat(15) begin
        #20 a1 = a1+1'b1;
        a2 = a2-1'b1;
    end
    #20//port1 reads 15-0, port2 writes 0-15
    we2 = 1'b1;
    repeat(15) begin
        #20 a1 = a1-1'b1;
        a2 = a2+1'b1;
        din2 = din2+1'b1;
    end
    #20 / / write 0-15 synchronously, port1 write 1, port2 write 2
    we1 = 1'b1;
    we2 = 1'b1;
    a1 = 4'b0000;
    a2 = 4'b0000;
    repeat(15) begin
        #20 a1 = a1+1'b1;
        din1 = 1'b1;
        a2 = a2+1'b1;
        din2 = 2'd2;
    end   
end
//sram_dp_srsw inst (
//  .clk(clk),
//  .a1(a1),      // input wire [3 : 0] a
//  .d1(d1),      // input wire [7 : 0] d
//  .we1(we1),    // input wire we
//  .cs1(cs1), 
//  .oe1(oe1),  
//  .a2(a2),      // input wire [3 : 0] a
//  .d2(d2),      // input wire [7 : 0] d
//  .we2(we2),    // input wire we
//  .cs2(cs2), 
//  .oe2(oe2)  
//);
sram_dp_araw inst (
  .a1(a1),      // input wire [3 : 0] a
  .d1(d1),      // input wire [7 : 0] d
  .we1(we1),    // input wire we
  .cs1(cs1), 
  .oe1(oe1),  
  .a2(a2),      // input wire [3 : 0] a
  .d2(d2),      // input wire [7 : 0] d
  .we2(we2),    // input wire we
  .cs2(cs2), 
  .oe2(oe2)  
);
endmodule

The simulation results are as follows:

 

 

The results of dual port synchronous read / write SRAM are as follows:

Compared with the results of dual port synchronous read-write SRAM, it is found that dual port asynchronous read-write SRAM is indeed independent of clk, and the related operation is performed when the control signal changes;

3, References:

Design of dual port RAM in FPGA (asynchronous reading and writing)

Verilog realizes RAM(5-dual port synchronous read / write SRAM)

 

 

Published 16 original articles, won praise 4, visited 5413
Private letter follow

Tags: Verilog

Posted on Tue, 25 Feb 2020 01:35:33 -0500 by verycleanteeth