-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmpram_reg.v
76 lines (70 loc) · 4.92 KB
/
mpram_reg.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2013, University of British Columbia (UBC); All rights reserved. //
// //
// Redistribution and use in source and binary forms, with or without //
// modification, are permitted provided that the following conditions are met: //
// * Redistributions of source code must retain the above copyright //
// notice, this list of conditions and the following disclaimer. //
// * Redistributions in binary form must reproduce the above copyright //
// notice, this list of conditions and the following disclaimer in the //
// documentation and/or other materials provided with the distribution. //
// * Neither the name of the University of British Columbia (UBC) nor the names //
// of its contributors may be used to endorse or promote products //
// derived from this software without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE //
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// mpram_reg.v: generic register-based multiported-RAM. //
// Reading addresses are registered and old data will be read in case of RAW. //
// Implemented in FF's if the number of reading or writing ports exceeds one. //
// //
// Author: Ameer M. Abdelhadi ([email protected], [email protected]) //
// SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module mpram_reg
#( parameter MEMD = 16, // memory depth
parameter DATAW = 32, // data width
parameter nRPORTS = 3 , // number of reading ports
parameter nWPORTS = 2 , // number of writing ports
parameter RDW = 0 , // provide new data when Read-During-Write?
parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over INITFILE)
parameter IFILE = "" // initialization hex file (don't pass extension), optional
)( input clk , // clock
input [nWPORTS-1:0 ] WEnb , // write enable for each writing port
input [`log2(MEMD)*nWPORTS-1:0] WAddr, // write addresses - packed from nWPORTS write ports
input [DATAW *nWPORTS-1:0] WData, // write data - packed from nRPORTS read ports
input [`log2(MEMD)*nRPORTS-1:0] RAddr, // read addresses - packed from nRPORTS read ports
output reg [DATAW *nRPORTS-1:0] RData // read data - packed from nRPORTS read ports
);
localparam ADDRW = `log2(MEMD); // address width
integer i;
// initialize RAM, with zeros if IZERO or file if IFLE.
(* ramstyle = "logic" *) reg [DATAW-1:0] mem [0:MEMD-1]; // memory array; implemented with logic cells (registers)
initial
if (IZERO)
for (i=0; i<MEMD; i=i+1) mem[i] = {DATAW{1'b0}};
else
if (IFILE != "") $readmemh({IFILE,".hex"}, mem);
always @(posedge clk) begin
// write to nWPORTS ports; nonblocking statement to read old data
for (i=1; i<=nWPORTS; i=i+1)
if (WEnb[i-1])
if (RDW) mem[WAddr[i*ADDRW-1 -: ADDRW]] = WData[i*DATAW-1 -: DATAW]; // blocking statement (= ) to read new data
else mem[WAddr[i*ADDRW-1 -: ADDRW]] <= WData[i*DATAW-1 -: DATAW]; // non-blocking statement (<=) to read old data
// Read from nRPORTS ports; nonblocking statement to read old data
for (i=1; i<=nRPORTS; i=i+1)
if (RDW) RData[i*DATAW-1 -: DATAW] = mem[RAddr[i*ADDRW-1 -: ADDRW]]; // blocking statement (= ) to read new data
else RData[i*DATAW-1 -: DATAW] <= mem[RAddr[i*ADDRW-1 -: ADDRW]]; //non-blocking statement (<=) to read old data
end
endmodule