├── LICENSE ├── README ├── README.md ├── config.vh ├── dpram.v ├── dpram_be.v ├── fpga2014-paper.pdf ├── fpga2014-slides.pdf ├── lvt_1ht.v ├── lvt_bin.v ├── lvt_reg.v ├── mpram.qpf ├── mpram.qsf ├── mpram.v ├── mpram_gen.v ├── mpram_gen_be.v ├── mpram_lvt_1ht.v ├── mpram_lvt_bin.v ├── mpram_lvt_reg.v ├── mpram_reg.v ├── mpram_tb.v ├── mpram_wrp.v ├── mpram_xor.v ├── mrram.v ├── mrram_be.v ├── sim ├── syn ├── syn.res.example └── utils.vh /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, University of British Columbia (UBC) All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | * Neither the name of the University of British Columbia (UBC) nor the names 11 | of its contributors may be used to endorse or promote products 12 | derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | #################################################################################### 2 | Copyright (c) 2014, University of British Columbia (UBC) All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the University of British Columbia (UBC) nor the names 12 | of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | #################################################################################### 26 | 27 | #################################################################################### 28 | Modular Multi-ported SRAM-based Memories; University of British Columbia, 2014 29 | Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) 30 | 31 | A fully parameterized and generic Verilog implementation of the suggested 32 | modular multi-ported SRAM-based memories, together with previous approaches 33 | are provided as open source hardware. A run-in-batch flow manager to simulate 34 | and synthesize various designs with various parameters in batch using Altera's 35 | ModelSim and Quartus II is also provided. 36 | 37 | Please refer to the full paper for more information: 38 | A. Abdelhadi and G. G.F. Lemieux, "Modular Multi-ported SRAM-based Memories," 39 | ACM/SIGDA Intl Symp. on Field-Programmable. Gate Arrays (FPGA 14), Feb. 2014. 40 | http://www.ece.ubc.ca/~lemieux/publications/abdelhadi-fpga2014.pdf 41 | 42 | LICENSE: BSD 3-Clause ("BSD New" or "BSD Simplified") license. 43 | #################################################################################### 44 | 45 | #################################################################################### 46 | Files and directories in this package: 47 | ====================================== 48 | - README : This file 49 | - LICENSE : BSD 3-Clause ("BSD New" or "BSD Simplified") license 50 | - fpga14-paper.pdf : ACM/SIGDA Intl Symp. on Field-Programmable. Gate Arrays (FPGA'14) paper 51 | - fpga14-slides.pdf: ACM/SIGDA Intl Symp. on Field-Programmable. Gate Arrays (FPGA'14) slides 52 | - sim : A C-shell script: A run-in-batch simulation flow manager 53 | - syn : A C-shell script: A run-in-batch synthesis flow manager 54 | - config.vh : Verilog: Generated by syn script, contains design parameters 55 | - utils.vh : Verilog: Design pre-compile utilities 56 | - mrram.v : Verilog: Multiread-RAM using bank replication; based on generic 57 | dual-ported RAM; optional 1 or 2-stage bypass 58 | - dpram.v : Verilog: Generic dual-ported RAM/ optional 1 or 2-stage bypass 59 | - mpram_gen.v : Verilog: Generic multiported-RAM; Old data will be read in case of RAW 60 | - mpram_reg.v : Verilog: Generic register-based multiported-RAM 61 | - mpram_xor.v : Verilog: Multiported-RAM based on XOR implementation 62 | - lvt_reg.v : Verilog: Register-based binary-coded LVT (Live-Value-Table) 63 | - lvt_bin.v : Verilog: Binary-coded LVT (Live-Value-Table) 64 | - lvt_1ht.v : Verilog: Onehot-coded LVT (Live-Value-Table) 65 | - mpram_lvt_reg.v : Verilog: Multiported-RAM based on register-based LVT 66 | - mpram_lvt_bin.v : Verilog: Multiported-RAM based on binary-coded LVT 67 | - mpram_lvt_1ht.v : Verilog: Multiported-RAM based on onehot-coded LVT 68 | - mpram.v : Verilog: Multiported-RAM: top hierarchy 69 | - mpram_tb.v : Verilog: Multiported-RAM testbench 70 | - mpram_wrp.v : Verilog: Multiported-RAM synthesis wrapper 71 | - mpram.qpf : Quartus II Project File 72 | - mpram.qsf : Quartus II Settings File 73 | - syn.res : A list of synthesis results, each run in a separate line, including: 74 | frequency, resources usage, and runtime 75 | - syn.res.example : Example results for 628 different designs 76 | - sim.res : A list of simulation results, each run in a separate line, 77 | including all design styles 78 | - log/ : Altera's logs and reports 79 | #################################################################################### 80 | 81 | #################################################################################### 82 | Multi-ported RAM module instantiation: 83 | ======================================= 84 | 85 | All *.v & *.vh files in this package should be copied into your work directory. 86 | Copy the following instantiation, change parameters and connectivity to fit your 87 | design. 88 | 89 | // instantiate a multiported-RAM 90 | mpram #( .MEMD (MEMD ), // positive integer: memory depth 91 | .DATAW (DATAW ), // positive integer: data width 92 | .nRPORTS(nRPORTS), // positive integer: number of reading ports 93 | .nWPORTS(nWPORTS), // positive integer: number of writing ports 94 | .TYPE (TYPE ), // text: multi-port RAM implementation type: 95 | // "AUTO" : Choose automatically 96 | // "REG" : Register-based 97 | // "XOR" : XOR-based 98 | // "LVTREG": Register-based LVT 99 | // "LVTBIN": Binary-coded I-LVT-based 100 | // "LVT1HT": Onehot-coded I-LVT-based 101 | .BYP (BYP ), // text: Bypassing type: 102 | // WAW: Allow Write-After-Write 103 | // (need to bypass feedback ram) 104 | // RAW: New data for Read-after-Write 105 | // (need to bypass output ram) 106 | // RDW: New data for Read-During-Write 107 | .IFILE ("" )) // text: initializtion file, optional 108 | mpram_inst ( .clk (clk ), // clock 109 | .WEnb (WEnb ), // write enable for each writing port 110 | // - input : [nWPORTS-1:0 ] 111 | .WAddr(WAddr), // write addresses - packed from nWPORTS write ports 112 | // - input : [`log2(MEMD)*nWPORTS-1:0] 113 | .WData(WData), // write data - packed from nRPORTS read ports 114 | // - output: [DATAW *nWPORTS-1:0] 115 | .RAddr(RAddr), // read addresses - packed from nRPORTS read ports 116 | // - input : [`log2(MEMD)*nRPORTS-1:0] 117 | .RData(RData)); // read data - packed from nRPORTS read ports 118 | // - output: [DATAW *nRPORTS-1:0] 119 | #################################################################################### 120 | 121 | 122 | #################################################################################### 123 | sim: A run-in-batch flow manager for simulation 124 | =============================================== 125 | USAGE: 126 | ./sim <#WritePorts List> <#ReadPorts List> <#Cycles> 127 | 128 | -Use a comma delimited list; no spaces; can be surrounded by brackets ()[]{}<> 129 | -RAM depth, width, number of read/write ports and cycles are positive integers 130 | 131 | EXAMPLES: 132 | ./sim 1024 32 3 2 1000000 133 | Simulate 1M cycles of a 1K lines RAM, 32 bits width, 3 write & 2 read ports 134 | ./sim 512,1024 8,16,32 2,3,4 1,2,3,4 1000000 135 | Simulate 1M cycles of RAMs with 512 or 1024 lines, 8, 16, or 32 bits width, 136 | 2,3, or 4 write ports, 1,2,3, or 4 read ports. Total of 72 RAM combinations 137 | 138 | The following files and directories will be created after simulation : 139 | - sim.res : A list of simulation results, each run in a separate line, 140 | including all design styles. 141 | #################################################################################### 142 | 143 | #################################################################################### 144 | syn: A run-in-batch flow manager for synthesis 145 | ============================================== 146 | USAGE: 147 | ./syn \ 148 | <#Write Ports List> <#Read Ports List> 149 | 150 | -Use a comma delimited list; no spaces; can be surrounded by brackets ()[]{}<> 151 | -RAM depth, width, number of read/write ports and cycles are positive integers 152 | -Architecture is one of: REG, XOR, LVTREG, LVTBIN, or LVT1HT 153 | - REG : Register-based multi-ported RAM 154 | - XOR : XOR-based multi-ported RAM 155 | - LVTREG: Register-based LVT multi-ported RAM 156 | - LVTBIN: Binary-coded I-LVT-based multi-ported RAM 157 | - LVT1HT: Onehot-coded I-LVT-based multi-ported RAM 158 | -Bypass list is one of: NON, WAW, RAW, or RDW 159 | - WAW: Allow Write-After-Write (need to bypass feedback RAM) 160 | - RAW: new data for Read-after-Write (need to bypass output RAM) 161 | - RDW: new data for Read-During-Write 162 | 163 | EXAMPLES: 164 | ./syn XOR NON 1024 32 3 2 165 | Synthesis a XOR-based RAM with no bypassing; 1K lines RAM; 32 bits width; 166 | 3 write & 2 read ports 167 | ./syn LVTBIN,LVT1HT RAW,RDW 512,1024 8,16,32 2,3,4 1,2,3,4 168 | Synthesis LVTBIN and LVT1HT RAMs with new data RAW and RDW bypassing; 512 169 | and 1024 lines; 8,16, and 32 data width; 2,3, and 4 write ports; 1,2,3, and 170 | 4 read ports. Total of 144 RAM combinations. 171 | 172 | The following files and directories will be created after compilation: 173 | - syn.res : A list of results, each run in a separate line, including: 174 | frequency, resources usage, and runtime 175 | - log/ : Altera's logs and reports 176 | #################################################################################### 177 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Modular Multi-ported SRAM-based Memories ## 2 | ## Ameer M. S. Abdelhadi and Guy G. F. Lemieux ## 3 | ## The University of British Columbia (UBC) 2014 ## 4 | ## { ameer.abdelhadi; guy.lemieux } @ gmail.com ## 5 | 6 | A fully parameterized and generic Verilog implementation of the suggested modular multi-ported SRAM-based memories, together with previous approaches are provided as open source hardware. A run-in-batch flow manager to simulate and synthesize various designs with various parameters in batch using Altera's ModelSim and Quartus II is also provided. 7 | 8 | **LICENSE:** BSD 3-Clause ("BSD New" or "BSD Simplified") license. 9 | 10 | Please refer to the full paper for more information: 11 | 12 | **A. M.S. Abdelhadi and G. G.F. Lemieux, "Modular Multi-ported SRAM-based Memories," ACM/SIGDA Intl Symp. on Field-Programmable. Gate Arrays (FPGA 14), Feb. 2014.** 13 | * **DOI:** http://dx.doi.org/10.1145/2554688.2554773 14 | * **Paper:** https://www.ece.mcmaster.ca/~ameer/publications/Abdelhadi-Conference-2014Feb-FPGA2014-MultiportedRAM.pdf 15 | * **Talk:** https://www.ece.mcmaster.ca/~ameer/publications/Abdelhadi-Talk-2014Feb-FPGA2014-MultiportedRAM.pdf 16 | 17 | --- 18 | 19 | 20 | ## Files and directories in this package ## 21 | * **README :** Read this first! 22 | * **LICENSE :** BSD 3-Clause ("BSD New" or "BSD Simplified") license 23 | * **fpga14-paper.pdf :** ACM/SIGDA Intl Symp. on Field-Programmable. Gate Arrays (FPGA'14) paper 24 | * **fpga14-slides.pdf:** ACM/SIGDA Intl Symp. on Field-Programmable. Gate Arrays (FPGA'14) slides 25 | * **sim :** A C-shell script: A run-in-batch simulation flow manager 26 | * **syn :** A C-shell script: A run-in-batch synthesis flow manager 27 | * **config.vh :** Verilog: Generated by syn script, contains design parameters 28 | * **utils.vh :** Verilog: Design pre-compile utilities 29 | * **mrram.v :** Verilog: Multiread-RAM using bank replication; based on generic dual-ported RAM; optional 1 or 2-stage bypass 30 | * **dpram.v :** Verilog: Generic dual-ported RAM/ optional 1 or 2-stage bypass 31 | * **mpram\_gen.v :** Verilog: Generic multiported-RAM; Old data will be read in case of RAW 32 | * **mpram\_reg.v :** Verilog: generic register-based multiported-RAM 33 | * **mpram\_xor.v :** Verilog: Multiported-RAM based on XOR implementation 34 | * **lvt\_reg.v :** Verilog: Register-based binary-coded LVT (Live-Value-Table) 35 | * **lvt\_bin.v :** Verilog: Binary-coded LVT (Live-Value-Table) 36 | * **lvt\_1ht.v :** Verilog: Onehot-coded LVT (Live-Value-Table) 37 | * **mpram\_lvt\_reg.v :** Verilog: Multiported-RAM based on register-based LVT 38 | * **mpram\_lvt\_bin.v :** Verilog: Multiported-RAM based on binary-coded LVT 39 | * **mpram\_lvt\_1ht.v :** Verilog: Multiported-RAM based on onehot-coded LVT 40 | * **mpram.v :** Verilog: Multiported-RAM: top hierarchy 41 | * **mpram\_tb.v :** Verilog: Multiported-RAM testbench 42 | * **mpram\_wrp.v :** Verilog: Multiported-RAM synthesis wrapper 43 | * **mpram.qpf :** Quartus II Project File 44 | * **mpram.qsf :** Quartus II Settings File 45 | * **syn.res :** A list of synthesis results, each run in a separate line, including: frequency, resources usage, and runtime 46 | * **syn.res.example :** Example results for 628 different designs 47 | * **sim.res :** A list of simulation results, each run in a separate line, including all design styles 48 | * **log/ :** Altera's logs and reports 49 | 50 | 51 | --- 52 | 53 | 54 | ## Multi-ported RAM module instantiation ## 55 | 56 | All **.v &**.vh files in this package should be copied into your work directory. 57 | Copy the following instantiation, change parameters and connectivity to fit your design. 58 | ``` 59 | // instantiate a multiported-RAM 60 | mpram #( .MEMD (MEMD ), // positive integer: memory depth 61 | .DATAW (DATAW ), // positive integer: data width 62 | .nRPORTS(nRPORTS), // positive integer: number of reading ports 63 | .nWPORTS(nWPORTS), // positive integer: number of writing ports 64 | .TYPE (TYPE ), // text: multi-port RAM implementation type: 65 | // "AUTO" : Choose automatically 66 | // "REG" : Register-based 67 | // "XOR" : XOR-based 68 | // "LVTREG": Register-based LVT 69 | // "LVTBIN": Binary-coded I-LVT-based 70 | // "LVT1HT": Onehot-coded I-LVT-based 71 | .BYP (BYP ), // text: Bypassing type: 72 | // WAW: Allow Write-After-Write 73 | // (need to bypass feedback ram) 74 | // RAW: New data for Read-after-Write 75 | // (need to bypass output ram) 76 | // RDW: New data for Read-During-Write 77 | .IFILE ("" )) // text: initializtion file, optional 78 | mpram_inst ( .clk (clk ), // clock 79 | .WEnb (WEnb ), // write enable for each writing port 80 | // - input : [nWPORTS-1:0 ] 81 | .WAddr(WAddr), // write addresses - packed from nWPORTS write ports 82 | // - input : [`log2(MEMD)*nWPORTS-1:0] 83 | .WData(WData), // write data - packed from nRPORTS read ports 84 | // - output: [DATAW *nWPORTS-1:0] 85 | .RAddr(RAddr), // read addresses - packed from nRPORTS read ports 86 | // - input : [`log2(MEMD)*nRPORTS-1:0] 87 | .RData(RData)); // read data - packed from nRPORTS read ports 88 | // - output: [DATAW *nRPORTS-1:0] 89 | ``` 90 | 91 | 92 | --- 93 | 94 | 95 | ## sim: A run-in-batch flow manager for simulation ## 96 | 97 | ### USAGE: ### 98 | 99 | `./sim <#WritePorts List> <#ReadPorts List> <#Cycles>` 100 | 101 | * Use a comma delimited list; no spaces; can be surrounded by brackets (), [], {}, <> 102 | * RAM depth, width, number of read/write ports and cycles are positive integers 103 | 104 | ### EXAMPLES: ### 105 | 106 | * `./sim 1024 32 3 2 1000000` 107 | * Simulate 1M cycles of a 1K lines RAM, 32 bits width, 3 write & 2 read ports 108 | * `./sim 512,1024 8,16,32 2,3,4 1,2,3,4 1000000` 109 | * Simulate 1M cycles of RAMs with 512 or 1024 lines, 8, 16, or 32 bits width, 2,3, or 4 write ports, 1,2,3, or 4 read ports. Total of 72 RAM combinations 110 | 111 | The following files and directories will be created after simulation: 112 | * sim.res : A list of simulation results, each run in a separate line, including all design styles 113 | 114 | 115 | --- 116 | 117 | 118 | ## syn: A run-in-batch flow manager for synthesis ## 119 | 120 | ### USAGE: ### 121 | 122 | `./syn <#Write Ports List> <#Read Ports List>` 123 | 124 | * Use a comma delimited list; no spaces; can be surrounded by brackets (), [], {}, <> 125 | * RAM depth, width, number of read/write ports and cycles are positive integers 126 | * Architecture is one of: REG, XOR, LVTREG, LVTBIN, or LVT1HT 127 | * REG : Register-based multi-ported RAM 128 | * XOR : XOR-based multi-ported RAM 129 | * LVTREG: Register-based LVT multi-ported RAM 130 | * LVTBIN: Binary-coded I-LVT-based multi-ported RAM 131 | * LVT1HT: Onehot-coded I-LVT-based multi-ported RAM 132 | * Bypass list is one of: NON, WAW, RAW, or RDW 133 | * WAW: Allow Write-After-Write (need to bypass feedback RAM) 134 | * RAW: new data for Read-after-Write (need to bypass output RAM) 135 | * RDW: new data for Read-During-Write 136 | 137 | ### EXAMPLES: ### 138 | 139 | * `./syn XOR NON 1024 32 3 2` 140 | * Synthesis a XOR-based RAM with no bypassing; 1K lines RAM; 32 bits width; 3 write & 2 read ports 141 | * `./syn LVTBIN,LVT1HT RAW,RDW 512,1024 8,16,32 2,3,4 1,2,3,4` 142 | * Synthesis LVTBIN and LVT1HT RAMs with new data RAW and RDW bypassing; 512 and 1024 lines; 8,16, and 32 data width; 2,3, and 4 write ports; 1,2,3, and 4 read ports. Total of 144 RAM combinations. 143 | 144 | The following files and directories will be created after compilation: 145 | * syn.res : A list of results, each run in a separate line, including: frequency, resources usage, and runtime 146 | * log/ : Altera's logs and reports 147 | 148 | -------------------------------------------------------------------------------- /config.vh: -------------------------------------------------------------------------------- 1 | // Multi-ported RAM Configuration File 2 | // Generated by flow manager before logic synthesis 3 | `define TYPE "LVTBIN" // Implementation: REG, XOR, LVTREG, LVTBIN, LVT1HT 4 | `define BYP "NON" // Bypass: NON, WAW, RAW, RDW 5 | `define MEMD 128 // RAM Depth (lines) 6 | `define DATAW 8 // Data Width (bits) 7 | `define nWPORTS 3 // Number of writing ports (>1) 8 | `define nRPORTS 3 // Number of reading ports 9 | -------------------------------------------------------------------------------- /dpram.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) 2013, University of British Columbia (UBC); All rights reserved. // 3 | // // 4 | // Redistribution and use in source and binary forms, with or without // 5 | // modification, are permitted provided that the following conditions are met: // 6 | // * Redistributions of source code must retain the above copyright // 7 | // notice, this list of conditions and the following disclaimer. // 8 | // * Redistributions in binary form must reproduce the above copyright // 9 | // notice, this list of conditions and the following disclaimer in the // 10 | // documentation and/or other materials provided with the distribution. // 11 | // * Neither the name of the University of British Columbia (UBC) nor the names // 12 | // of its contributors may be used to endorse or promote products // 13 | // derived from this software without specific prior written permission. // 14 | // // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // 16 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // 17 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // 18 | // DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE // 19 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // 20 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // 21 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // 22 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // 23 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // 24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 25 | //////////////////////////////////////////////////////////////////////////////////// 26 | 27 | //////////////////////////////////////////////////////////////////////////////////// 28 | //dpram.v: Generic dual-ported RAM with optional single-stage or two-stage bypass.// 29 | // // 30 | // Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `include "utils.vh" 35 | 36 | module dpram 37 | #( parameter MEMD = 16, // memory depth 38 | parameter DATAW = 32, // data width 39 | parameter BYPASS = 1 , // bypass? 0:none; 1: single-stage; 2: two-stage 40 | parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over IFILE) 41 | parameter IFILE = "" // initialization hex file (don't pass extension), optional 42 | )( input clk , // clock 43 | input WEnb , // write enable for each writing port 44 | input [`log2(MEMD)-1:0] WAddr, // write addresses - packed from nWPORTS write ports 45 | input [DATAW -1:0] WData, // write data - packed from nRPORTS read ports 46 | input [`log2(MEMD)-1:0] RAddr, // read addresses - packed from nRPORTS read ports 47 | output reg [DATAW -1:0] RData // read data - packed from nRPORTS read ports 48 | ); 49 | 50 | wire [DATAW-1:0] RData_i; // read ram data (internal) - packed from nRPORTS read ports 51 | mpram_gen #( .MEMD (MEMD ), // memory depth 52 | .DATAW (DATAW ), // data width 53 | .nRPORTS(1 ), // number of reading ports 54 | .nWPORTS(1 ), // number of writing ports 55 | .IZERO (IZERO ), // binary / Initial RAM with zeros (has priority over INITFILE) 56 | .IFILE (IFILE )) // initializtion file, optional 57 | dpram_inst ( .clk (clk ), // clock 58 | .WEnb (WEnb ), // write enable for each writing port - in : [nWPORTS-1:0 ] 59 | .WAddr (WAddr ), // write addresses - packed from nWPORTS write ports - in : [`log2(MEMD)*nWPORTS-1:0] 60 | .WData (WData ), // write data - packed from nRPORTS read ports - out: [DATAW *nWPORTS-1:0] 61 | .RAddr (RAddr ), // read addresses - packed from nRPORTS read ports - in : [`log2(MEMD)*nRPORTS-1:0] 62 | .RData (RData_i)); // read data - packed from nRPORTS read ports - out: [DATAW *nRPORTS-1:0] 63 | 64 | // registers; will be removed if unused 65 | reg WEnb_r; 66 | reg [`log2(MEMD)-1:0] WAddr_r; 67 | reg [`log2(MEMD)-1:0] RAddr_r; 68 | reg [DATAW-1:0] WData_r; 69 | always @(posedge clk) begin 70 | WEnb_r <= WEnb ; 71 | WAddr_r <= WAddr; 72 | RAddr_r <= RAddr; 73 | WData_r <= WData; // bypass register 74 | end 75 | 76 | // bypass: single-staeg, two-stage (logic will be removed if unused) 77 | wire bypass1,bypass2; 78 | assign bypass1 = (BYPASS >= 1) && WEnb_r && (WAddr_r == RAddr_r); 79 | assign bypass2 = (BYPASS == 2) && WEnb && (WAddr == RAddr_r); 80 | 81 | // output mux (mux or mux inputs will be removed if unused) 82 | always @* 83 | if (bypass2) RData = WData ; 84 | else if (bypass1) RData = WData_r; 85 | else RData = RData_i; 86 | 87 | endmodule 88 | -------------------------------------------------------------------------------- /dpram_be.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) 2013, University of British Columbia (UBC); All rights reserved. // 3 | // // 4 | // Redistribution and use in source and binary forms, with or without // 5 | // modification, are permitted provided that the following conditions are met: // 6 | // * Redistributions of source code must retain the above copyright // 7 | // notice, this list of conditions and the following disclaimer. // 8 | // * Redistributions in binary form must reproduce the above copyright // 9 | // notice, this list of conditions and the following disclaimer in the // 10 | // documentation and/or other materials provided with the distribution. // 11 | // * Neither the name of the University of British Columbia (UBC) nor the names // 12 | // of its contributors may be used to endorse or promote products // 13 | // derived from this software without specific prior written permission. // 14 | // // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // 16 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // 17 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // 18 | // DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE // 19 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // 20 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // 21 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // 22 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // 23 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // 24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 25 | //////////////////////////////////////////////////////////////////////////////////// 26 | 27 | //////////////////////////////////////////////////////////////////////////////////// 28 | //dpram.v: Generic dual-ported RAM with optional single-stage or two-stage bypass.// 29 | // // 30 | // Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `include "utils.vh" 35 | 36 | module dpram_be 37 | #( parameter MEMD = 16, // memory depth 38 | parameter DATAW = 32, // data width 39 | parameter BYPASS = 1 , // bypass? 0:none; 1: single-stage; 2: two-stage 40 | parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over IFILE) 41 | parameter IFILE = "" // initialization hex file (don't pass extension), optional 42 | )( input clk , // clock 43 | input WEnb , // write enable for each writing port 44 | input [`log2(MEMD)-1:0] WAddr, // write addresses - packed from nWPORTS write ports 45 | input [(DATAW/8) -1:0] WBe, 46 | input [DATAW -1:0] WData, // write data - packed from nRPORTS read ports 47 | input [`log2(MEMD)-1:0] RAddr, // read addresses - packed from nRPORTS read ports 48 | output reg [DATAW -1:0] RData // read data - packed from nRPORTS read ports 49 | ); 50 | 51 | wire [DATAW-1:0] RData_i; // read ram data (internal) - packed from nRPORTS read ports 52 | mpram_gen_be #( .MEMD (MEMD ), // memory depth 53 | .DATAW (DATAW ), // data width 54 | .nRPORTS(1 ), // number of reading ports 55 | .nWPORTS(1 ), // number of writing ports 56 | .IZERO (IZERO ), // binary / Initial RAM with zeros (has priority over INITFILE) 57 | .IFILE (IFILE )) // initializtion file, optional 58 | dpram_inst ( .clk (clk ), // clock 59 | .WEnb (WEnb ), // write enable for each writing port - in : [nWPORTS-1:0 ] 60 | .WAddr (WAddr ), // write addresses - packed from nWPORTS write ports - in : [`log2(MEMD)*nWPORTS-1:0] 61 | .WBe (WBe ), 62 | .WData (WData ), // write data - packed from nRPORTS read ports - out: [DATAW *nWPORTS-1:0] 63 | .RAddr (RAddr ), // read addresses - packed from nRPORTS read ports - in : [`log2(MEMD)*nRPORTS-1:0] 64 | .RData (RData_i)); // read data - packed from nRPORTS read ports - out: [DATAW *nRPORTS-1:0] 65 | 66 | // registers; will be removed if unused 67 | reg WEnb_r; 68 | reg [`log2(MEMD)-1:0] WAddr_r; 69 | reg [`log2(MEMD)-1:0] RAddr_r; 70 | reg [DATAW-1:0] WData_r; 71 | always @(posedge clk) begin 72 | WEnb_r <= WEnb ; 73 | WAddr_r <= WAddr; 74 | RAddr_r <= RAddr; 75 | WData_r <= WData; // bypass register 76 | end 77 | 78 | // bypass: single-staeg, two-stage (logic will be removed if unused) 79 | wire bypass1,bypass2; 80 | assign bypass1 = (BYPASS >= 1) && WEnb_r && (WAddr_r == RAddr_r); 81 | assign bypass2 = (BYPASS == 2) && WEnb && (WAddr == RAddr_r); 82 | 83 | // output mux (mux or mux inputs will be removed if unused) 84 | // FIXME 85 | always @* 86 | if (bypass2) RData = WData ; 87 | else if (bypass1) RData = WData_r; 88 | else RData = RData_i; 89 | 90 | endmodule 91 | -------------------------------------------------------------------------------- /fpga2014-paper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerAbdelhadi/Multiported-RAM/5f969563865bbca27100fc2a292f17688ad1fbcc/fpga2014-paper.pdf -------------------------------------------------------------------------------- /fpga2014-slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerAbdelhadi/Multiported-RAM/5f969563865bbca27100fc2a292f17688ad1fbcc/fpga2014-slides.pdf -------------------------------------------------------------------------------- /lvt_1ht.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) 2013, University of British Columbia (UBC); All rights reserved. // 3 | // // 4 | // Redistribution and use in source and binary forms, with or without // 5 | // modification, are permitted provided that the following conditions are met: // 6 | // * Redistributions of source code must retain the above copyright // 7 | // notice, this list of conditions and the following disclaimer. // 8 | // * Redistributions in binary form must reproduce the above copyright // 9 | // notice, this list of conditions and the following disclaimer in the // 10 | // documentation and/or other materials provided with the distribution. // 11 | // * Neither the name of the University of British Columbia (UBC) nor the names // 12 | // of its contributors may be used to endorse or promote products // 13 | // derived from this software without specific prior written permission. // 14 | // // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // 16 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // 17 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // 18 | // DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE // 19 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // 20 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // 21 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // 22 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // 23 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // 24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 25 | //////////////////////////////////////////////////////////////////////////////////// 26 | 27 | //////////////////////////////////////////////////////////////////////////////////// 28 | // lvt_1ht.v: Onehot-coded LVT (Live-Value-Table) // 29 | // // 30 | // Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `include "utils.vh" 35 | 36 | module lvt_1ht 37 | #( parameter MEMD = 16, // memory depth 38 | parameter DATAW = 32, // data width 39 | parameter nRPORTS = 1 , // number of reading ports 40 | parameter nWPORTS = 3 , // number of writing ports 41 | parameter WAW = 1 , // allow Write-After-Write (need to bypass feedback ram) 42 | parameter RAW = 1 , // new data for Read-after-Write (need to bypass output ram) 43 | parameter RDW = 0 , // new data for Read-During-Write 44 | parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over IFILE) 45 | parameter IFILE = "" // initialization file, optional 46 | )( input clk , // clock 47 | input [ nWPORTS-1:0] WEnb , // write enable for each writing port 48 | input [`log2(MEMD)*nWPORTS-1:0] WAddr, // write addresses - packed from nWPORTS write ports 49 | input [`log2(MEMD)*nRPORTS-1:0] RAddr, // read addresses - packed from nRPORTS read ports 50 | output reg [nWPORTS *nRPORTS-1:0] RBank); // read bank selector - packed from nRPORTS read ports 51 | 52 | localparam ADDRW = `log2(MEMD); // address width 53 | localparam LVTW = nWPORTS - 1; // required memory width 54 | 55 | // Register write addresses, data and enables 56 | reg [ADDRW*nWPORTS-1:0] WAddr_r; // registered write addresses - packed from nWPORTS write ports 57 | reg [ nWPORTS-1:0] WEnb_r ; // registered write enable for each writing port 58 | always @(posedge clk) begin 59 | WAddr_r <= WAddr; 60 | WEnb_r <= WEnb ; 61 | end 62 | 63 | // unpacked/pack addresses and data 64 | reg [ADDRW -1:0] WAddr2D [nWPORTS-1:0] ; // write addresses / 2D 65 | reg [ADDRW -1:0] WAddr2D_r [nWPORTS-1:0] ; // registered write addresses / 2D 66 | wire [LVTW *nRPORTS-1:0] RDataOut2D [nWPORTS-1:0] ; // read data out / 2D 67 | reg [LVTW -1:0] RDataOut3D [nWPORTS-1:0][nRPORTS-1:0]; // read data out / 3D 68 | reg [ADDRW*LVTW -1:0] RAddrFB2D [nWPORTS-1:0] ; // read address fb / 2D 69 | reg [ADDRW -1:0] RAddrFB3D [nWPORTS-1:0][LVTW -1:0]; // read address fb / 3D 70 | wire [LVTW *LVTW -1:0] RDataFB2D [nWPORTS-1:0] ; // read data fb / 2D 71 | reg [LVTW -1:0] RDataFB3D [nWPORTS-1:0][LVTW -1:0]; // read data fb / 3D 72 | reg [LVTW -1:0] WDataFB2D [nWPORTS-1:0] ; // write data / 2D 73 | reg [LVTW -1:0] InvData2D [nWPORTS-1:0] ; // write data / 2D 74 | reg [nWPORTS -1:0] RBank2D [nRPORTS-1:0] ; // read bank selector / 2D 75 | `ARRINIT; 76 | always @* begin 77 | `ARR1D2D(nWPORTS, ADDRW,WAddr ,WAddr2D ); 78 | `ARR1D2D(nWPORTS, ADDRW,WAddr_r ,WAddr2D_r ); 79 | `ARR2D1D(nRPORTS,nWPORTS ,RBank2D ,RBank ); 80 | `ARR2D3D(nWPORTS,nRPORTS,LVTW ,RDataOut2D,RDataOut3D); 81 | `ARR3D2D(nWPORTS,LVTW ,ADDRW,RAddrFB3D ,RAddrFB2D ); 82 | `ARR2D3D(nWPORTS,LVTW ,LVTW ,RDataFB2D ,RDataFB3D ); 83 | end 84 | 85 | // generate and instantiate mulriread BRAMs 86 | genvar wpi; 87 | generate 88 | for (wpi=0 ; wpi0)&&(IFILE!="")), // binary / Initial RAM with zeros (has priority over IFILE) 107 | .IFILE (IFILE )) // initialization file, optional 108 | mrram_fdb ( .clk (clk ), // clock - in 109 | .WEnb (WEnb_r[wpi] ), // write enable (1 port) - in 110 | .WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0] 111 | .WBe (WBe2D_r[wpi] ), 112 | .WData (WDataFB2D[wpi] ), // write data (1 port) - in : [DATAW -1:0] 113 | .RAddr (RAddrFB2D[wpi] ), // read addresses - packed from nRPORTS read ports - in : [`log2(MEMD)*nRPORTS-1:0] 114 | .RData (RDataFB2D[wpi] )); // read data - packed from nRPORTS read ports - out: [DATAW *nRPORTS-1:0] 115 | // output multiread ram instantiation 116 | mrram_be #( .MEMD (MEMD ), // memory depth 117 | .DATAW (DATAW ), // data width 118 | .nRPORTS(nRPORTS ), // number of reading ports 119 | .BYPASS (RDW ? 2 : RAW ), // bypass? 0:none; 1:single-stage; 2:two-stages 120 | .IZERO ((wpi>0)&&(IFILE!="")), // binary / Initial RAM with zeros (has priority over IFILE) 121 | .IFILE (IFILE )) // initialization file, optional 122 | mrram_out ( .clk (clk ), // clock - in 123 | .WEnb (WEnb_r[wpi] ), // write enable (1 port) - in 124 | .WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0] 125 | .WBe (WBe2D_r[wpi] ), 126 | .WData (WDataFB2D[wpi] ), // write data (1 port) - in : [DATAW -1:0] 127 | .RAddr (RAddr ), // read addresses - packed from nRPORTS read ports - in : [`log2(MEMD)*nRPORTS-1:0] 128 | .RData (RDataOut2D[wpi] )); // read data - packed from nRPORTS read ports - out: [DATAW *nRPORTS-1:0] 129 | 130 | end 131 | endgenerate 132 | 133 | // combinatorial logic for output and feedback functions 134 | integer i,j,k,n; 135 | always @* begin 136 | // generate output read functions 137 | for(i=0;i <#WritePorts List> <#ReadPorts List> <#Cycles> ## 39 | ## ## 40 | ## -Use a comma delimited list; no spaces; can be surrounded by brackets ()[]{}<> ## 41 | ## -RAM depth, width, number of read/write ports and cycles are positive integers ## 42 | ## ## 43 | ## EXAMPLES: ## 44 | ## ./sim 1024 32 3 2 1000000 ## 45 | ## Simulate 1M cycles of a 1K lines RAM, 32 bits width, 3 write & 2 read ports ## 46 | ## ./sim 512,1024 8,16,32 2,3,4 1,2,3,4 1000000 ## 47 | ## Simulate 1M cycles of RAMs with 512 or 1024 lines, 8, 16, or 32 bits width, ## 48 | ## 2,3, or 4 write ports, 1,2,3, or 4 read ports. Total of 72 RAM combinations ## 49 | ## ## 50 | ## The following files and directories will be created after simulation : ## 51 | ## - sim.res : A list of simulation results, each run in a separate line, ## 52 | ## including all design styles. ## 53 | #################################################################################### 54 | 55 | # setup environment variables and cad tools 56 | # change if necessary 57 | #source env.csh 58 | 59 | # setup Altera's Modelsim for simulation; change to your own flow if necessary 60 | source /CMC/scripts/altera.12.0.csh 61 | setenv PATH ${QUARTUS_HOME}/../nios2eds/bin/:${QUARTUS_HOME}/../modelsim_ase/bin:${PATH} 62 | 63 | # create work if not exist 64 | if !(-d work) vlib work 65 | 66 | # require exactly 5 arguments 67 | if (${#argv} != 5) then 68 | printf '\x1b[%i;3%im' 1 1 69 | printf 'Error: Exactly 5 are required\n' 70 | printf '\x1b[0m' 71 | goto errorMessage 72 | endif 73 | 74 | # convert each argument list into a c-shell list (romove commas and etc.) 75 | set RDLST = (`echo ${argv[1]} | tr ",()[]{}<>" " "`) 76 | set DWLST = (`echo ${argv[2]} | tr ",()[]{}<>" " "`) 77 | set NWLST = (`echo ${argv[3]} | tr ",()[]{}<>" " "`) 78 | set NRLST = (`echo ${argv[4]} | tr ",()[]{}<>" " "`) 79 | set CYCC = ${argv[5]} 80 | 81 | # check arguments correctness (positive integer numbers) 82 | foreach ARGVAL ($RDLST $DWLST $NWLST $NRLST $CYCC) 83 | set ARGVALIsNumber=`echo $ARGVAL | egrep -c '^[0-9]+$'` 84 | if ($ARGVALIsNumber != 1) then 85 | printf '\x1b[%i;3%im' 1 1 86 | printf "Error \(${INTVAL}\): Depth, width, numner of read/write ports arguments should be possitive integer numbers\n" 87 | printf '\x1b[0m' 88 | goto errorMessage 89 | endif 90 | end 91 | 92 | # total different fifo designs 93 | @ FlowOprNum = ((${#RDLST})*(${#DWLST})*(${#NWLST})*(${#NRLST})) 94 | @ FlowOprCnt = 0 95 | 96 | printf '\x1b[%i;3%im' 7 4 97 | printf "= Simulate in batch with the following parameters:\n" 98 | printf "= RAM Depth : $RDLST\n" 99 | printf "= Data Width : $DWLST\n" 100 | printf "= Write Ports : $NWLST\n" 101 | printf "= Read Ports : $NRLST\n" 102 | printf "= Simulation Cycles : $CYCC\n" 103 | printf '\x1b[0m' 104 | 105 | # operate on all different RAM parameters 106 | foreach CURRD ($RDLST) 107 | foreach CURDW ($DWLST) 108 | foreach CURNW ($NWLST) 109 | foreach CURNR ($NRLST) 110 | @ FlowOprCnt++ 111 | 112 | printf '\x1b[%i;3%im' 7 2 113 | printf "\n== Starting Simulation (${FlowOprCnt}/${FlowOprNum}): [Depth:${CURRD}; Width:${CURDW}; Writes:${CURNW}; Reads:${CURNR}; Cycles:${CYCC}]\n" 114 | printf '\x1b[0m' 115 | 116 | # run current simulation 117 | vlog -work work +define+MEMD=$CURRD+DATAW=$CURDW+nWPORTS=$CURNW+nRPORTS=$CURNR+CYCC=$CYCC dpram.v lvt_bin.v mpram_gen.v mpram_lvt_bin.v mpram_reg.v mpram.v mpram_xor.v utils.vh lvt_1ht.v lvt_reg.v mpram_lvt_1ht.v mpram_lvt_reg.v mpram_tb.v mrram.v 118 | vsim -c -L altera_mf_ver -L lpm_ver -do "run -all" mpram_tb 119 | 120 | printf '\x1b[%i;3%im' 7 2 121 | printf "== Simulation (${FlowOprCnt}/${FlowOprNum}) Completed: [Depth:${CURRD}; Width:${CURDW}; Writes:${CURNW}; Reads:${CURNR}; Cycles:${CYCC}]\n" 122 | printf '\x1b[0m' 123 | 124 | end 125 | end 126 | end 127 | end 128 | 129 | # clean unrequired files / after run 130 | foreach fileName (*.mif *.hex *.ver *.wlf *.vstf *.log transcript work) 131 | \rm -rf $fileName 132 | end 133 | 134 | 135 | goto scriptEnd 136 | 137 | # error message 138 | errorMessage: 139 | printf '\x1b[%i;3%im' 1 1 140 | printf 'USAGE:\n' 141 | printf './sim <#WritePorts List> <#ReadPorts List> <#Cycles>\n' 142 | printf '-Use a comma delimited list; no spaces; can be surrounded by brackets ()[]{}<>\n' 143 | printf '-RAM depth, width, number of read/write ports and cycles are positive integers\n' 144 | printf 'EXAMPLES:\n' 145 | printf './sim 1024 32 3 2 1000000\n' 146 | printf ' Simulate 1M cycles of a 1K lines RAM, 32 bits width, 3 write & 2 read ports\n' 147 | printf './sim 512,1024 8,16,32 2,3,4 1,2,3,4 1000000\n' 148 | printf ' Simulate 1M cycles of RAMs with 512 or 1024 lines, 8, 16, or 32 bits width,\n' 149 | printf ' 2,3, or 4 write ports, 1,2,3, or 4 read ports. Total of 72 RAM combinations\n' 150 | printf 'The following files and directories will be created after simulation : \n' 151 | printf ' - sim.res : A list of simulation results, each run in a separate line, \n' 152 | printf ' including all design styles. \n' 153 | printf '\x1b[0m' 154 | scriptEnd: 155 | 156 | -------------------------------------------------------------------------------- /syn: -------------------------------------------------------------------------------- 1 | #!/bin/csh -f 2 | 3 | #################################################################################### 4 | ## Copyright (c) 2014, University of British Columbia (UBC) All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions are met: ## 8 | ## * Redistributions of source code must retain the above copyright ## 9 | ## notice, this list of conditions and the following disclaimer. ## 10 | ## * Redistributions in binary form must reproduce the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer in the ## 12 | ## documentation and/or other materials provided with the distribution. ## 13 | ## * Neither the name of the University of British Columbia (UBC) nor the names ## 14 | ## of its contributors may be used to endorse or promote products ## 15 | ## derived from this software without specific prior written permission. ## 16 | ## ## 17 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ## 18 | ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## 19 | ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ## 20 | ## DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE ## 21 | ## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## 22 | ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## 23 | ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 24 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## 25 | ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## 26 | ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## 27 | #################################################################################### 28 | 29 | #################################################################################### 30 | ## Run-in-batch Synthesis Flow Manager ## 31 | ## ## 32 | ## Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) ## 33 | ## SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 ## 34 | #################################################################################### 35 | 36 | #################################################################################### 37 | ## USAGE: ## 38 | ## ./syn \ ## 39 | ## <#Write Ports List> <#Read Ports List> ## 40 | ## ## 41 | ## -Use a comma delimited list; no spaces; can be surrounded by brackets ()[]{}<> ## 42 | ## -RAM depth, width, number of read/write ports and cycles are positive integers ## 43 | ## -Architecture is one of: REG, XOR, LVTREG, LVTBIN, or LVT1HT ## 44 | ## - REG : Register-based multi-ported RAM ## 45 | ## - XOR : XOR-based multi-ported RAM ## 46 | ## - LVTREG: Register-based LVT multi-ported RAM ## 47 | ## - LVTBIN: Binary-coded I-LVT-based multi-ported RAM ## 48 | ## - LVT1HT: Onehot-coded I-LVT-based multi-ported RAM ## 49 | ## -Bypass list is one of: NON, WAW, RAW, or RDW ## 50 | ## - WAW: Allow Write-After-Write (need to bypass feedback RAM) ## 51 | ## - RAW: new data for Read-after-Write (need to bypass output RAM) ## 52 | ## - RDW: new data for Read-During-Write ## 53 | ## ## 54 | ## EXAMPLES: ## 55 | ## ./syn XOR NON 1024 32 3 2 ## 56 | ## Synthesis a XOR-based RAM with no bypassing; 1K lines RAM; 32 bits width; ## 57 | ## 3 write & 2 read ports ## 58 | ## ./syn LVTBIN,LVT1HT RAW,RDW 512,1024 8,16,32 2,3,4 1,2,3,4 ## 59 | ## Synthesis LVTBIN and LVT1HT RAMs with new data RAW and RDW bypassing; 512 ## 60 | ## and 1024 lines; 8,16, and 32 data width; 2,3, and 4 write ports; 1,2,3, and ## 61 | ## 4 read ports. Total of 144 RAM combinations. ## 62 | ## ## 63 | ## The following files and directories will be created after compilation: ## 64 | ## - syn.res : A list of results, each run in a separate line, including: ## 65 | ## frequency, resources usage, and runtime ## 66 | ## - log/ : Altera's logs and reports ## 67 | #################################################################################### 68 | 69 | # setup environment variables and cad tools 70 | # change if necessary 71 | #source env.csh 72 | 73 | # setup Altera's tools; change to your own flow if necessary 74 | source /CMC/scripts/altera.12.0.csh 75 | setenv PATH ${QUARTUS_HOME}/../nios2eds/bin/:${QUARTUS_HOME}/../modelsim_ase/bin:${PATH} 76 | 77 | # require exactly 6 arguments 78 | if (${#argv} != 6) then 79 | printf '\x1b[%i;3%im' 1 1 80 | printf 'Error: Exactly 6 are required\n' 81 | printf '\x1b[0m' 82 | goto errorMessage 83 | endif 84 | 85 | # convert each argument list into a c-shell list (romove commas and etc.) 86 | set ARLST = (`echo ${argv[1]} | tr ",()[]{}<>" " "`) 87 | set BYLST = (`echo ${argv[2]} | tr ",()[]{}<>" " "`) 88 | set RDLST = (`echo ${argv[3]} | tr ",()[]{}<>" " "`) 89 | set DWLST = (`echo ${argv[4]} | tr ",()[]{}<>" " "`) 90 | set NWLST = (`echo ${argv[5]} | tr ",()[]{}<>" " "`) 91 | set NRLST = (`echo ${argv[6]} | tr ",()[]{}<>" " "`) 92 | 93 | # check arguments correctness (positive integer numbers) 94 | foreach INTVAL ($RDLST $DWLST $NWLST $NRLST) 95 | set INTVALIsNumber=`echo $INTVAL | egrep -c '^[0-9]+$'` 96 | if ($INTVALIsNumber != 1) then 97 | printf '\x1b[%i;3%im' 1 1 98 | printf "Error \(${INTVAL}\): Depth, width, numner of read/write ports arguments should be possitive integer numbers\n" 99 | printf '\x1b[0m' 100 | goto errorMessage 101 | endif 102 | end 103 | 104 | # check architicture list argument correctness 105 | foreach ARVAL ($ARLST) 106 | if ( ($ARVAL != "REG") & ($ARVAL != "XOR") & ($ARVAL != "LVTREG") & ($ARVAL != "LVTBIN") & ($ARVAL != "LVT1HT") ) then 107 | printf '\x1b[%i;3%im' 1 1 108 | printf "Error \(${ARVAL}\): Architicture list should be a list of REG, XOR, LVTREG, LVTBIN, or LVT1HT\b\n" 109 | printf '\x1b[0m' 110 | goto errorMessage 111 | endif 112 | end 113 | 114 | # check architicture list argument correctness 115 | foreach BYVAL ($BYLST) 116 | if ( ($BYVAL != "NON") & ($BYVAL != "WAW") & ($BYVAL != "RAW") & ($BYVAL != "RDW") ) then 117 | printf '\x1b[%i;3%im' 1 1 118 | printf "Error \(${BYVAL}\): BYpass list should be a list of NON, WAW, RAW, or RDW\b\n" 119 | printf '\x1b[0m' 120 | goto errorMessage 121 | endif 122 | end 123 | 124 | # total different fifo designs 125 | @ FlowOprNum = ((${#RDLST})*(${#DWLST})*(${#NWLST})*(${#NRLST})*(${#ARLST})*(${#BYLST})) 126 | @ FlowOprCnt = 0 127 | 128 | printf '\x1b[%i;3%im' 7 4 129 | printf "= Synthesis in batch with the following parameters:\n" 130 | printf "= RAM Depth : $RDLST\n" 131 | printf "= Data Width : $DWLST\n" 132 | printf "= Write Ports : $NWLST\n" 133 | printf "= Read Ports : $NRLST\n" 134 | printf "= Architicture : $ARLST\n" 135 | printf "= Bypass : $BYLST\n" 136 | printf '\x1b[0m' 137 | 138 | #print header 139 | set FML = `grep " FAMILY " mpram.qsf | cut -d\" -f2` 140 | set DEV = `grep " DEVICE " mpram.qsf | cut -d" " -f4` 141 | set TTL1 = ' FmaxMHz 0.95v A L U T s Combinatorial ALUTs by LUT #inputs Combinatorial ALUTs by Mode Registers L A B s I / O Pins BRAM Bits Utiliz. \n' 142 | set TTL2 = ' RAM Data Write Read ------------- -------------------- ---------------------------------- --------------------------- ------------- Total ----------------- ----------- BRAM MLAB ----------------- Runtime\n' 143 | set TTL3 = 'Arch. Bypass Depth Width Ports Ports T = 0c T=100c Total Combi. Memory 7-LUTs 6-LUTs 5-LUTs 4-LUTs 3-LUTs Normal exten. Arith. Shared Total Dedic. ALMs Total Logic Mem. Tot Clk Ded M20K Bits Utilized Occupied DSPs Minutes\n' 144 | set SEPR = '====== ====== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ===== ===== ===== === === === ==== ==== ======== ======== ==== =======\n' 145 | set FRMT = (`echo $SEPR| tr " " "\n" | perl -nle '$a= length; print "%-${a}s"' | tr "\n" " "`) 146 | if !(-f syn.res) then 147 | printf "$FML $DEV\n\n$TTL1$TTL2$TTL3$SEPR" >! syn.res 148 | endif 149 | 150 | #initialize result values 151 | set val = (`repeat 35 echo "N/A"`) 152 | 153 | # create log directoy 154 | if !(-d log) mkdir log 155 | 156 | # operate on all different RAM parameters 157 | foreach CURRD ($RDLST) 158 | foreach CURDW ($DWLST) 159 | foreach CURNW ($NWLST) 160 | foreach CURNR ($NRLST) 161 | foreach CURAR ($ARLST) 162 | foreach CURBY ($BYLST) 163 | 164 | @ FlowOprCnt++ 165 | set curRunStartTime = `date +%T` 166 | set curRunStartTimeStamp = `date +%s` 167 | set RUNNAME = "${CURAR}_${CURRD}x${CURDW}-${CURNW}W${CURNR}R" 168 | 169 | printf '\x1b[%i;3%im' 7 2 170 | printf "\n== Starting Synthesis (${FlowOprCnt}/${FlowOprNum}) @${curRunStartTime}: [Depth:${CURRD}; Width:${CURDW}; Writes:${CURNW}; Reads:${CURNR}; Architicture:${CURAR}]\n" 171 | printf '\x1b[0m' 172 | 173 | # create configuration file base on architectural 174 | printf '// Multi-ported RAM Configuration File\n' >! config.vh 175 | printf '// Generated by flow manager before logic synthesis\n' >> config.vh 176 | printf '`define TYPE "%s"\t// Implementation: REG, XOR, LVTREG, LVTBIN, LVT1HT\n' $CURAR >> config.vh 177 | printf '`define BYP "%s"\t\t// Bypass: NON, WAW, RAW, RDW\n' $CURBY >> config.vh 178 | printf '`define MEMD %s\t\t// RAM Depth (lines) \n' $CURRD >> config.vh 179 | printf '`define DATAW %s\t\t// Data Width (bits) \n' $CURDW >> config.vh 180 | printf '`define nWPORTS %s\t\t// Number of writing ports (>1)\n' $CURNW >> config.vh 181 | printf '`define nRPORTS %s\t\t// Number of reading ports\n' $CURNR >> config.vh 182 | 183 | # clean previous report files before run 184 | foreach fileName (mpram.asm.rpt mpram.eda.rpt mpram.fit.rpt mpram.flow.rpt mpram.map.rpt mpram.sta.rpt mpram.done mpram.fit.summary mpram.map.summary mpram.sta.summary mpram.pin mpram.sof) 185 | if (-e $fileName) \rm -rf $fileName 186 | end 187 | 188 | # clean previous values before run 189 | set val = (`repeat 35 echo "N/A"`) 190 | 191 | # run current synthesis 192 | quartus_map --64bit --read_settings_files=on --write_settings_files=off mpram -c mpram | tee log/${RUNNAME}.map.log 193 | quartus_cdb --64bit --merge mpram -c mpram | tee log/${RUNNAME}.cdb.log 194 | quartus_fit --64bit --read_settings_files=off --write_settings_files=off mpram -c mpram | tee log/${RUNNAME}.fit.log 195 | quartus_sta --64bit mpram -c mpram | tee log/${RUNNAME}.sta.log 196 | 197 | # calculate runtime and generate a report / per run 198 | set curRunFinishTime = `date +%T` 199 | set curRunFinishTimeStamp = `date +%s` 200 | @ curRunTimeDiff = $curRunFinishTimeStamp - $curRunStartTimeStamp 201 | set curRuntimeMin = `echo "scale=2;$curRunTimeDiff/60"|bc` 202 | 203 | # collect data 204 | set val[1] = $CURAR 205 | set val[2] = $CURBY 206 | set val[3] = $CURRD 207 | set val[4] = $CURDW 208 | set val[5] = $CURNW 209 | set val[6] = $CURNR 210 | if (-f mpram.sta.rpt) then 211 | set val[7] = `grep -a4 "Slow 900mV 0C Model Fmax Summary" mpram.sta.rpt | tail -1 | cut -d" " -f2 | tr -d " \n"`; 212 | set val[8] = `grep -a4 "Slow 900mV 85C Model Fmax Summary" mpram.sta.rpt | tail -1 | cut -d" " -f2 | tr -d " \n"` 213 | endif 214 | if (-f mpram.fit.rpt) then 215 | grep -A100 "; Fitter Resource Usage Summary" mpram.fit.rpt >! FitterResourceUsageSummary.tmp 216 | set val[9] = `grep ";\s*ALUTs Used\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 217 | set val[10] = `grep ";\s*-- Combinational ALUTs\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 218 | set val[11] = `grep ";\s*-- Memory ALUTs\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 219 | set val[12] = `grep ";\s*-- 7 input functions\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 220 | set val[13] = `grep ";\s*-- 6 input functions\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 221 | set val[14] = `grep ";\s*-- 5 input functions\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 222 | set val[15] = `grep ";\s*-- 4 input functions\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 223 | set val[16] = `grep ";\s*-- <=3 input functions\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 224 | set val[17] = `grep ";\s*-- normal mode\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 225 | set val[18] = `grep ";\s*-- extended LUT mode\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 226 | set val[19] = `grep ";\s*-- arithmetic mode\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 227 | set val[20] = `grep ";\s*-- shared arithmetic mode\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 228 | set val[21] = `grep ";\s*Total registers\*\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 229 | set val[22] = `grep ";\s*-- Dedicated logic registers\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 230 | set val[23] = `grep ";\s*ALMs: partially or completely used\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 231 | set val[24] = `grep ";\s*Total LABs: partially or completely used\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 232 | set val[25] = `grep ";\s*-- Logic LABs\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 233 | set val[26] = `grep ";\s*-- Memory LABs\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 234 | set val[27] = `grep ";\s*I/O pins\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 235 | set val[28] = `grep ";\s*-- Clock pins\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 236 | set val[29] = `grep ";\s*-- Dedicated input pins\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 237 | set val[30] = `grep ";\s*M20K blocks \s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 238 | set val[31] = `grep ";\s*Total MLAB memory bits\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 239 | set val[32] = `grep ";\s*Total block memory bits\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 240 | set val[33] = `grep ";\s*Total block memory implementation bits\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 241 | set val[34] = `grep ";\s*Total DSP Blocks\s*;" FitterResourceUsageSummary.tmp | cut -d";" -f3 | cut -d"/" -f1| tr -d ", "` 242 | set val[35] = $curRuntimeMin 243 | \rm -rf FitterResourceUsageSummary.tmp 244 | endif 245 | foreach i (`seq 35`) 246 | if ( $val[$i] == "" ) set val[$i] = "N/A" 247 | end 248 | 249 | # print to report 250 | printf "$FRMT\n" $val >> syn.res 251 | 252 | # move log files into log directory 253 | foreach fileName (mpram.asm.rpt mpram.eda.rpt mpram.fit.rpt mpram.flow.rpt mpram.map.rpt mpram.sta.rpt mpram.done mpram.fit.summary mpram.map.summary mpram.sta.summary mpram.pin) 254 | if (-f $fileName) mv $fileName "log/${RUNNAME}.`echo $fileName | cut -d. -f2-`" 255 | end 256 | 257 | printf '\x1b[%i;3%im' 7 2 258 | printf "== Synthesis (${FlowOprCnt}/${FlowOprNum}) Completed after ${curRuntimeMin} minutes: [Depth:${CURRD}; Width:${CURDW}; Writes:${CURNW}; Reads:${CURNR}; Architicture:${CURAR}]\n" 259 | printf '\x1b[0m' 260 | 261 | end 262 | end 263 | end 264 | end 265 | end 266 | end 267 | 268 | # clean unrequired files / after run 269 | foreach fileName (db/ hc_output/ incremental_db/ mpram.asm.rpt mpram.eda.rpt mpram.merge.rpt mpram.fit.rpt mpram.flow.rpt mpram.map.rpt mpram.sta.rpt mpram.done mpram.merge.summary mpram.fit.summary mpram.fit.smsg mpram.map.summary mpram.sta.summary mpram.pin mpram.sof) 270 | if (-e $fileName) \rm -rf $fileName 271 | end 272 | 273 | goto scriptEnd 274 | 275 | # error message 276 | errorMessage: 277 | printf '\x1b[%i;3%im' 1 1 278 | printf 'USAGE: \n' 279 | printf ' ./syn \ \n' 280 | printf ' <#Write Ports List> <#Read Ports List> \n' 281 | printf '-Use a comma delimited list; no spaces; can be surrounded by brackets ()[]{}<>\n' 282 | printf '-RAM depth, width, number of read/write ports and cycles are positive integers\n' 283 | printf '-Architicture is one of: REG, XOR, LVTREG, LVTBIN, or LVT1HT \n' 284 | printf ' - REG : Register-based multi-ported RAM \n' 285 | printf ' - XOR : XOR-based nulti-ported RAM \n' 286 | printf ' - LVTREG: Register-based LVT multi-ported RAM \n' 287 | printf ' - LVTBIN: Binary-coded I-LVT-based multi-ported RAM \n' 288 | printf ' - LVT1HT: onehot-coded I-LVT-based multi-ported RAM \n' 289 | printf '-Bypass list is one of: NON, WAW, RAW , RDW (new data Read After/During Write)\n' 290 | printf ' - WAW: Allow Write-After-Write (need to bypass feedback RAM) \n' 291 | printf ' - RAW: new data for Read-after-Write (need to bypass output RAM) \n' 292 | printf ' - RDW: new data for Read-During-Write \n' 293 | printf 'EXAMPLES: \n' 294 | printf './syn XOR NON 1024 32 3 2 \n' 295 | printf ' Synthesis a XOR-based RAM with no bypassing; 1K lines RAM; 32 bits width; \n' 296 | printf ' 3 write & 2 read ports \n' 297 | printf './syn LVTBIN,LVT1HT RAW,RDW 512,1024 8,16,32 2,3,4 1,2,3,4 \n' 298 | printf ' Synthesis LVTBIN and LVT1HT RAMs with new data RAW and RDW bypassing; 512 \n' 299 | printf ' and 1024 lines; 8,16, and 32 data width; 2,3, and 4 write ports; 1,2,3, and\n' 300 | printf ' 4 read ports. Total of 144 RAM combinations. \n' 301 | printf 'The following files and directories will be created after compilation: \n' 302 | printf ' - syn.res : A list of results, each run in a separate line, including: \n' 303 | printf ' frequency, resources usage, and runtime \n' 304 | printf ' - log/ : Alteras logs and reports \n' 305 | printf '\x1b[0m' 306 | scriptEnd: 307 | 308 | -------------------------------------------------------------------------------- /utils.vh: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) 2013, University of British Columbia (UBC); All rights reserved. // 3 | // // 4 | // Redistribution and use in source and binary forms, with or without // 5 | // modification, are permitted provided that the following conditions are met: // 6 | // * Redistributions of source code must retain the above copyright // 7 | // notice, this list of conditions and the following disclaimer. // 8 | // * Redistributions in binary form must reproduce the above copyright // 9 | // notice, this list of conditions and the following disclaimer in the // 10 | // documentation and/or other materials provided with the distribution. // 11 | // * Neither the name of the University of British Columbia (UBC) nor the names // 12 | // of its contributors may be used to endorse or promote products // 13 | // derived from this software without specific prior written permission. // 14 | // // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // 16 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // 17 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // 18 | // DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE // 19 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // 20 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // 21 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // 22 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // 23 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // 24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 25 | //////////////////////////////////////////////////////////////////////////////////// 26 | 27 | //////////////////////////////////////////////////////////////////////////////////// 28 | // utils.vh: Design utilities (pre-compile) // 29 | // // 30 | // Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `ifndef __UTILS_VH__ 35 | `define __UTILS_VH__ 36 | 37 | `define DEBUG_MODE // debug mode, comment this line for other modes 38 | `define VERBOSE // verbose debug, comment this line for other modes 39 | 40 | // Initiate Array structure - use once before calling packing/unpacking modules 41 | `define ARRINIT integer _i_,_j_ 42 | // pack/unpack 1D/2D/3D arrays; use in "always @*" if combinatorial 43 | `define ARR2D1D(D1W,D2W, SRC,DST) for(_i_=1;_i_<=(D1W);_i_=_i_+1) DST[((D2W)*_i_-1)-:D2W] = SRC[_i_-1] 44 | `define ARR1D2D(D1W,D2W, SRC,DST) for(_i_=1;_i_<=(D1W);_i_=_i_+1) DST[_i_-1] = SRC[((D2W)*_i_-1)-:D2W] 45 | `define ARR2D3D(D1W,D2W,D3W,SRC,DST) for(_i_=0;_i_< (D1W);_i_=_i_+1) for(_j_=1;_j_<=(D2W);_j_=_j_+1) DST[_i_][_j_-1] = SRC[_i_][((D3W)*_j_-1)-:D3W] 46 | `define ARR3D2D(D1W,D2W,D3W,SRC,DST) for(_i_=0;_i_< (D1W);_i_=_i_+1) for(_j_=1;_j_<=(D2W);_j_=_j_+1) DST[_i_][((D3W)*_j_-1)-:D3W] = SRC[_i_][_j_-1] 47 | 48 | // print a 2-D array in a comma-delimited list 49 | `define ARRPRN(ARRLEN,PRNSRC) for (_i_=(ARRLEN)-1;_i_>=0;_i_=_i_-1) $write("%c%h%c",(_i_==(ARRLEN)-1)?"[":"",PRNSRC[_i_],!_i_?"]":",") 50 | // Initialize a vector with a specific width random number; extra bits are zero padded 51 | `define GETRAND(RAND,RANDW) RAND=0; repeat ((RANDW)/32) RAND=(RAND<<32)|{$random}; RAND=(RAND<<((RANDW)%32))|({$random}>>(32-(RANDW)%32)) 52 | 53 | // factorial (n!) 54 | `define fact(n) ( ( ((n) >= 2 ) ? 2 : 1) * \ 55 | ( ((n) >= 3 ) ? 3 : 1) * \ 56 | ( ((n) >= 4 ) ? 4 : 1) * \ 57 | ( ((n) >= 5 ) ? 5 : 1) * \ 58 | ( ((n) >= 6 ) ? 6 : 1) * \ 59 | ( ((n) >= 7 ) ? 7 : 1) * \ 60 | ( ((n) >= 8 ) ? 8 : 1) * \ 61 | ( ((n) >= 9 ) ? 9 : 1) * \ 62 | ( ((n) >= 10 ) ? 10 : 1) ) 63 | 64 | // ceiling of log2 65 | `define log2(x) ( ( ((x) > 1 ) ? 1 : 0) + \ 66 | ( ((x) > 2 ) ? 1 : 0) + \ 67 | ( ((x) > 4 ) ? 1 : 0) + \ 68 | ( ((x) > 8 ) ? 1 : 0) + \ 69 | ( ((x) > 16 ) ? 1 : 0) + \ 70 | ( ((x) > 32 ) ? 1 : 0) + \ 71 | ( ((x) > 64 ) ? 1 : 0) + \ 72 | ( ((x) > 128 ) ? 1 : 0) + \ 73 | ( ((x) > 256 ) ? 1 : 0) + \ 74 | ( ((x) > 512 ) ? 1 : 0) + \ 75 | ( ((x) > 1024 ) ? 1 : 0) + \ 76 | ( ((x) > 2048 ) ? 1 : 0) + \ 77 | ( ((x) > 4096 ) ? 1 : 0) + \ 78 | ( ((x) > 8192 ) ? 1 : 0) + \ 79 | ( ((x) > 16384 ) ? 1 : 0) + \ 80 | ( ((x) > 32768 ) ? 1 : 0) + \ 81 | ( ((x) > 65536 ) ? 1 : 0) + \ 82 | ( ((x) > 131072 ) ? 1 : 0) + \ 83 | ( ((x) > 262144 ) ? 1 : 0) + \ 84 | ( ((x) > 524288 ) ? 1 : 0) + \ 85 | ( ((x) > 1048576) ? 1 : 0) + \ 86 | ( ((x) > 2097152) ? 1 : 0) + \ 87 | ( ((x) > 4194304) ? 1 : 0) ) 88 | 89 | // floor of log2 90 | `define log2f(x) ( ( ((x) >= 2 ) ? 1 : 0) + \ 91 | ( ((x) >= 4 ) ? 1 : 0) + \ 92 | ( ((x) >= 8 ) ? 1 : 0) + \ 93 | ( ((x) >= 16 ) ? 1 : 0) + \ 94 | ( ((x) >= 32 ) ? 1 : 0) + \ 95 | ( ((x) >= 64 ) ? 1 : 0) + \ 96 | ( ((x) >= 128 ) ? 1 : 0) + \ 97 | ( ((x) >= 256 ) ? 1 : 0) + \ 98 | ( ((x) >= 512 ) ? 1 : 0) + \ 99 | ( ((x) >= 1024 ) ? 1 : 0) + \ 100 | ( ((x) >= 2048 ) ? 1 : 0) + \ 101 | ( ((x) >= 4096 ) ? 1 : 0) + \ 102 | ( ((x) >= 8192 ) ? 1 : 0) + \ 103 | ( ((x) >= 16384 ) ? 1 : 0) + \ 104 | ( ((x) >= 32768 ) ? 1 : 0) + \ 105 | ( ((x) >= 65536 ) ? 1 : 0) + \ 106 | ( ((x) >= 131072 ) ? 1 : 0) + \ 107 | ( ((x) >= 262144 ) ? 1 : 0) + \ 108 | ( ((x) >= 524288 ) ? 1 : 0) + \ 109 | ( ((x) >= 1048576) ? 1 : 0) + \ 110 | ( ((x) >= 2097152) ? 1 : 0) + \ 111 | ( ((x) >= 4194304) ? 1 : 0) ) 112 | 113 | `endif //__UTILS_VH__ 114 | --------------------------------------------------------------------------------