/**********************************************************************
|
/**********************************************************************
|
** File: generic_ram.v
|
** File: generic_ram.v
|
**
|
**
|
**
|
**
|
** Copyright (C) 2014-2017 Alireza Monemi
|
** Copyright (C) 2014-2017 Alireza Monemi
|
**
|
**
|
** This file is part of ProNoC
|
** This file is part of ProNoC
|
**
|
**
|
** ProNoC ( stands for Prototype Network-on-chip) is free software:
|
** ProNoC ( stands for Prototype Network-on-chip) is free software:
|
** you can redistribute it and/or modify it under the terms of the GNU
|
** you can redistribute it and/or modify it under the terms of the GNU
|
** Lesser General Public License as published by the Free Software Foundation,
|
** Lesser General Public License as published by the Free Software Foundation,
|
** either version 2 of the License, or (at your option) any later version.
|
** either version 2 of the License, or (at your option) any later version.
|
**
|
**
|
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
|
** ProNoC is distributed in the hope that it will be useful, but WITHOUT
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
** Public License for more details.
|
** Public License for more details.
|
**
|
**
|
** You should have received a copy of the GNU Lesser General Public
|
** You should have received a copy of the GNU Lesser General Public
|
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
|
** License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
|
**
|
**
|
**
|
**
|
** Description:
|
** Description:
|
** Generic single dual port ram
|
** Generic single dual port ram
|
**
|
**
|
**
|
**
|
*******************************************************************/
|
*******************************************************************/
|
|
|
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
|
|
|
|
/********************
|
/********************
|
* generic_dual_port_ram
|
* generic_dual_port_ram
|
********************/
|
********************/
|
|
|
module generic_dual_port_ram #(
|
module generic_dual_port_ram #(
|
parameter Dw=8,
|
parameter Dw=8,
|
parameter Aw=6,
|
parameter Aw=6,
|
parameter BYTE_WR_EN= "YES",//"YES","NO"
|
parameter BYTE_WR_EN= "YES",//"YES","NO"
|
parameter INITIAL_EN= "NO",
|
parameter INITIAL_EN= "NO",
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
)
|
)
|
(
|
(
|
data_a,
|
data_a,
|
data_b,
|
data_b,
|
addr_a,
|
addr_a,
|
addr_b,
|
addr_b,
|
byteena_a,
|
byteena_a,
|
byteena_b,
|
byteena_b,
|
we_a,
|
we_a,
|
we_b,
|
we_b,
|
clk,
|
clk,
|
q_a,
|
q_a,
|
q_b
|
q_b
|
);
|
);
|
|
|
|
/* verilator lint_off WIDTH */
|
localparam BYTE_ENw= ( BYTE_WR_EN == "YES")? Dw/8 : 1;
|
localparam BYTE_ENw= ( BYTE_WR_EN == "YES")? Dw/8 : 1;
|
|
/* verilator lint_on WIDTH */
|
|
|
input [(Dw-1):0] data_a, data_b;
|
input [(Dw-1):0] data_a, data_b;
|
input [(Aw-1):0] addr_a, addr_b;
|
input [(Aw-1):0] addr_a, addr_b;
|
input [BYTE_ENw-1 : 0] byteena_a, byteena_b;
|
input [BYTE_ENw-1 : 0] byteena_a, byteena_b;
|
input we_a, we_b, clk;
|
input we_a, we_b, clk;
|
output [(Dw-1):0] q_a, q_b;
|
output [(Dw-1):0] q_a, q_b;
|
|
|
generate
|
generate
|
|
/* verilator lint_off WIDTH */
|
if ( BYTE_WR_EN == "NO") begin : no_byten
|
if ( BYTE_WR_EN == "NO") begin : no_byten
|
|
/* verilator lint_on WIDTH */
|
dual_port_ram #(
|
dual_port_ram #(
|
.Dw (Dw),
|
.Dw (Dw),
|
.Aw (Aw),
|
.Aw (Aw),
|
.INITIAL_EN(INITIAL_EN),
|
.INITIAL_EN(INITIAL_EN),
|
.INIT_FILE(INIT_FILE)
|
.INIT_FILE(INIT_FILE)
|
)
|
)
|
the_ram
|
the_ram
|
(
|
(
|
.data_a (data_a),
|
.data_a (data_a),
|
.data_b (data_b),
|
.data_b (data_b),
|
.addr_a (addr_a),
|
.addr_a (addr_a),
|
.addr_b (addr_b),
|
.addr_b (addr_b),
|
.we_a (we_a),
|
.we_a (we_a),
|
.we_b (we_b),
|
.we_b (we_b),
|
.clk (clk),
|
.clk (clk),
|
.q_a (q_a),
|
.q_a (q_a),
|
.q_b (q_b)
|
.q_b (q_b)
|
);
|
);
|
|
|
end else begin : byten
|
end else begin : byten
|
|
|
byte_enabled_true_dual_port_ram #(
|
byte_enabled_true_dual_port_ram #(
|
.BYTE_WIDTH(8),
|
.BYTE_WIDTH(8),
|
.ADDRESS_WIDTH(Aw),
|
.ADDRESS_WIDTH(Aw),
|
.BYTES(Dw/8),
|
.BYTES(Dw/8),
|
.INITIAL_EN(INITIAL_EN),
|
.INITIAL_EN(INITIAL_EN),
|
.INIT_FILE(INIT_FILE)
|
.INIT_FILE(INIT_FILE)
|
|
|
)
|
)
|
the_ram
|
the_ram
|
(
|
(
|
.addr1 (addr_a),
|
.addr1 (addr_a),
|
.addr2 (addr_b),
|
.addr2 (addr_b),
|
.be1 (byteena_a),
|
.be1 (byteena_a),
|
.be2 (byteena_b),
|
.be2 (byteena_b),
|
.data_in1 (data_a),
|
.data_in1 (data_a),
|
.data_in2 (data_b),
|
.data_in2 (data_b),
|
.we1 (we_a),
|
.we1 (we_a),
|
.we2 (we_b),
|
.we2 (we_b),
|
.clk (clk),
|
.clk (clk),
|
.data_out1 (q_a),
|
.data_out1 (q_a),
|
.data_out2 (q_b)
|
.data_out2 (q_b)
|
);
|
);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************
|
/********************
|
* generic_single_port_ram
|
* generic_single_port_ram
|
********************/
|
********************/
|
|
|
|
|
|
|
module generic_single_port_ram #(
|
module generic_single_port_ram #(
|
parameter Dw=8,
|
parameter Dw=8,
|
parameter Aw=6,
|
parameter Aw=6,
|
parameter BYTE_WR_EN= "YES",//"YES","NO"
|
parameter BYTE_WR_EN= "YES",//"YES","NO"
|
parameter INITIAL_EN= "NO",
|
parameter INITIAL_EN= "NO",
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
)
|
)
|
(
|
(
|
data,
|
data,
|
addr,
|
addr,
|
byteen,
|
byteen,
|
we,
|
we,
|
clk,
|
clk,
|
q
|
q
|
|
|
);
|
);
|
|
/* verilator lint_off WIDTH */
|
localparam BYTE_ENw= ( BYTE_WR_EN == "YES")? Dw/8 : 1;
|
localparam BYTE_ENw= ( BYTE_WR_EN == "YES")? Dw/8 : 1;
|
|
/* verilator lint_on WIDTH */
|
|
|
input [(Dw-1):0] data;
|
input [(Dw-1):0] data;
|
input [(Aw-1):0] addr;
|
input [(Aw-1):0] addr;
|
input [BYTE_ENw-1 : 0] byteen;
|
input [BYTE_ENw-1 : 0] byteen;
|
input we, clk;
|
input we, clk;
|
output [(Dw-1):0] q;
|
output [(Dw-1):0] q;
|
|
|
generate
|
generate
|
|
/* verilator lint_off WIDTH */
|
if ( BYTE_WR_EN == "NO") begin : no_byten
|
if ( BYTE_WR_EN == "NO") begin : no_byten
|
|
/* verilator lint_on WIDTH */
|
|
|
single_port_ram #(
|
single_port_ram #(
|
.Dw (Dw),
|
.Dw (Dw),
|
.Aw (Aw),
|
.Aw (Aw),
|
.INITIAL_EN(INITIAL_EN),
|
.INITIAL_EN(INITIAL_EN),
|
.INIT_FILE(INIT_FILE)
|
.INIT_FILE(INIT_FILE)
|
)
|
)
|
the_ram
|
the_ram
|
(
|
(
|
.data (data),
|
.data (data),
|
.addr (addr),
|
.addr (addr),
|
.we (we),
|
.we (we),
|
.clk (clk),
|
.clk (clk),
|
.q (q)
|
.q (q)
|
);
|
);
|
|
|
end else begin : byten
|
end else begin : byten
|
|
|
byte_enabled_single_port_ram #(
|
byte_enabled_single_port_ram #(
|
.BYTE_WIDTH(8),
|
.BYTE_WIDTH(8),
|
.ADDRESS_WIDTH(Aw),
|
.ADDRESS_WIDTH(Aw),
|
.BYTES(Dw/8),
|
.BYTES(Dw/8),
|
.INITIAL_EN(INITIAL_EN),
|
.INITIAL_EN(INITIAL_EN),
|
.INIT_FILE(INIT_FILE)
|
.INIT_FILE(INIT_FILE)
|
|
|
)
|
)
|
the_ram
|
the_ram
|
(
|
(
|
.addr (addr),
|
.addr (addr),
|
.be (byteen),
|
.be (byteen),
|
.data_in(data),
|
.data_in(data),
|
.we (we),
|
.we (we),
|
.clk (clk),
|
.clk (clk),
|
.data_out(q)
|
.data_out(q)
|
);
|
);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************
|
/*******************
|
|
|
dual_port_ram
|
dual_port_ram
|
|
|
********************/
|
********************/
|
|
|
|
|
// Quartus II Verilog Template
|
// Quartus II Verilog Template
|
// True Dual Port RAM with single clock
|
// True Dual Port RAM with single clock
|
|
|
|
|
module dual_port_ram
|
module dual_port_ram
|
#(
|
#(
|
parameter Dw=8,
|
parameter Dw=8,
|
parameter Aw=6,
|
parameter Aw=6,
|
parameter INITIAL_EN= "NO",
|
parameter INITIAL_EN= "NO",
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file
|
)
|
)
|
(
|
(
|
data_a,
|
data_a,
|
data_b,
|
data_b,
|
addr_a,
|
addr_a,
|
addr_b,
|
addr_b,
|
we_a,
|
we_a,
|
we_b,
|
we_b,
|
clk,
|
clk,
|
q_a,
|
q_a,
|
q_b
|
q_b
|
);
|
);
|
|
|
|
|
input [(Dw-1):0] data_a, data_b;
|
input [(Dw-1):0] data_a, data_b;
|
input [(Aw-1):0] addr_a, addr_b;
|
input [(Aw-1):0] addr_a, addr_b;
|
input we_a, we_b, clk;
|
input we_a, we_b, clk;
|
output reg [(Dw-1):0] q_a, q_b;
|
output reg [(Dw-1):0] q_a, q_b;
|
|
|
// Declare the RAM variable
|
// Declare the RAM variable
|
reg [Dw-1:0] ram[2**Aw-1:0];
|
reg [Dw-1:0] ram[2**Aw-1:0];
|
|
|
// initial the memory if the file is defined
|
// initial the memory if the file is defined
|
generate
|
generate
|
|
/* verilator lint_off WIDTH */
|
if (INITIAL_EN == "YES") begin : init
|
if (INITIAL_EN == "YES") begin : init
|
|
/* verilator lint_on WIDTH */
|
initial $readmemh(INIT_FILE,ram);
|
initial $readmemh(INIT_FILE,ram);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
// Port A
|
// Port A
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if (we_a)
|
if (we_a)
|
begin
|
begin
|
ram[addr_a] <= data_a;
|
ram[addr_a] <= data_a;
|
q_a <= data_a;
|
q_a <= data_a;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
q_a <= ram[addr_a];
|
q_a <= ram[addr_a];
|
end
|
end
|
end
|
end
|
|
|
// Port B
|
// Port B
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if (we_b)
|
if (we_b)
|
begin
|
begin
|
ram[addr_b] <= data_b;
|
ram[addr_b] <= data_b;
|
q_b <= data_b;
|
q_b <= data_b;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
q_b <= ram[addr_b];
|
q_b <= ram[addr_b];
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
/****************
|
/****************
|
*simple_dual_port_ram
|
*simple_dual_port_ram
|
*
|
*
|
*****************/
|
*****************/
|
|
|
|
|
|
|
// Quartus II Verilog Template
|
// Quartus II Verilog Template
|
// Simple Dual Port RAM with separate read/write addresses and
|
// Simple Dual Port RAM with separate read/write addresses and
|
// single read/write clock
|
// single read/write clock
|
|
|
module simple_dual_port_ram #(
|
module simple_dual_port_ram #(
|
parameter Dw=8,
|
parameter Dw=8,
|
parameter Aw=6,
|
parameter Aw=6,
|
parameter INITIAL_EN= "NO",
|
parameter INITIAL_EN= "NO",
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
)
|
)
|
(
|
(
|
data,
|
data,
|
read_addr,
|
read_addr,
|
write_addr,
|
write_addr,
|
we,
|
we,
|
clk,
|
clk,
|
q
|
q
|
);
|
);
|
|
|
input [Dw-1 :0] data;
|
input [Dw-1 :0] data;
|
input [Aw-1 :0] read_addr;
|
input [Aw-1 :0] read_addr;
|
input [Aw-1 :0] write_addr;
|
input [Aw-1 :0] write_addr;
|
input we;
|
input we;
|
input clk;
|
input clk;
|
output reg [Dw-1 :0] q;
|
output reg [Dw-1 :0] q;
|
|
|
|
|
// Declare the RAM variable
|
// Declare the RAM variable
|
reg [Dw-1:0] ram [2**Aw-1:0];
|
reg [Dw-1:0] ram [2**Aw-1:0];
|
|
|
// initial the memory if the file is defined
|
// initial the memory if the file is defined
|
generate
|
generate
|
|
/* verilator lint_off WIDTH */
|
if (INITIAL_EN == "YES") begin : init
|
if (INITIAL_EN == "YES") begin : init
|
|
/* verilator lint_on WIDTH */
|
initial $readmemh(INIT_FILE,ram);
|
initial $readmemh(INIT_FILE,ram);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
// Write
|
// Write
|
if (we)
|
if (we)
|
ram[write_addr] <= data;
|
ram[write_addr] <= data;
|
|
|
// Read (if read_addr == write_addr, return OLD data). To return
|
// Read (if read_addr == write_addr, return OLD data). To return
|
// NEW data, use = (blocking write) rather than <= (non-blocking write)
|
// NEW data, use = (blocking write) rather than <= (non-blocking write)
|
// in the write assignment. NOTE: NEW data may require extra bypass
|
// in the write assignment. NOTE: NEW data may require extra bypass
|
// logic around the RAM.
|
// logic around the RAM.
|
q <= ram[read_addr];
|
q <= ram[read_addr];
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************
|
/*****************************
|
|
|
single_port_ram
|
single_port_ram
|
|
|
|
|
*****************************/
|
*****************************/
|
|
|
// Quartus II Verilog Template
|
// Quartus II Verilog Template
|
// Single port RAM with single read/write address
|
// Single port RAM with single read/write address
|
|
|
module single_port_ram #(
|
module single_port_ram #(
|
parameter Dw=8,
|
parameter Dw=8,
|
parameter Aw=6,
|
parameter Aw=6,
|
parameter INITIAL_EN= "NO",
|
parameter INITIAL_EN= "NO",
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
parameter INIT_FILE= "sw/ram/ram0.txt"// ram initial file in hex ascii format
|
)
|
)
|
(
|
(
|
data,
|
data,
|
addr,
|
addr,
|
we,
|
we,
|
clk,
|
clk,
|
q
|
q
|
);
|
);
|
|
|
input [(Dw-1):0] data;
|
input [(Dw-1):0] data;
|
input [(Aw-1):0] addr;
|
input [(Aw-1):0] addr;
|
input we, clk;
|
input we, clk;
|
output [(Dw-1):0] q;
|
output [(Dw-1):0] q;
|
|
|
// Declare the RAM variable
|
// Declare the RAM variable
|
reg [Dw-1:0] ram[2**Aw-1:0];
|
reg [Dw-1:0] ram[2**Aw-1:0];
|
|
|
// initial the memory if the file is defined
|
// initial the memory if the file is defined
|
generate
|
generate
|
|
/* verilator lint_off WIDTH */
|
if (INITIAL_EN == "YES") begin : init
|
if (INITIAL_EN == "YES") begin : init
|
|
/* verilator lint_on WIDTH */
|
initial $readmemh(INIT_FILE,ram);
|
initial $readmemh(INIT_FILE,ram);
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Variable to hold the registered read address
|
// Variable to hold the registered read address
|
reg [Aw-1:0] addr_reg;
|
reg [Aw-1:0] addr_reg;
|
|
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
// Write
|
// Write
|
if (we)
|
if (we)
|
ram[addr] <= data;
|
ram[addr] <= data;
|
addr_reg <= addr;
|
addr_reg <= addr;
|
end
|
end
|
|
|
// Continuous assignment implies read returns NEW data.
|
// Continuous assignment implies read returns NEW data.
|
// This is the natural behavior of the TriMatrix memory
|
// This is the natural behavior of the TriMatrix memory
|
// blocks in Single Port mode.
|
// blocks in Single Port mode.
|
assign q = ram[addr_reg];
|
assign q = ram[addr_reg];
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|