├── LICENSE ├── README ├── README.md ├── bcam.qpf ├── bcam.qsf ├── bcam.sdc ├── bcam.v ├── bcam_bhv.v ├── bcam_reg.v ├── bcam_str.v ├── bcam_tb.v ├── bcam_trc.v ├── bcam_trs.v ├── dpram_be.v ├── fpt2014-paper.pdf ├── fpt2014-slides.pdf ├── mux ├── mwram_gen.v ├── mwram_m20k.v ├── pe ├── reduction ├── sbram_m20k.v ├── sim ├── spram.v ├── syn ├── tdpram.v ├── trcam.v └── utils.vh /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, the University of British Columbia. 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 THE UNIVERSITY OF BRITISH COLUMBIA 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 | 2D Binary Content Addressable Memory; University of British Columbia, 2014 29 | Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) 30 | 31 | A fully parameterized and generic Verilog implementation of the suggested 32 | modular SRAM-based 2D hierarchical-search Binary Content Addressable Memory 33 | ,together with other approaches are provided as open source hardware. A run- 34 | in-batch flow manager to simulate and synthesize various designs with various 35 | parameters in batch using Altera's ModelSim and Quartus is also provided. 36 | 37 | Please refer to the full paper for more information: 38 | A. M.S. Abdelhadi and G. G.F. Lemieux, "Deep and Narrow Binary Content-Addressable 39 | Memories using FPGA-based BRAMs," International Conference on Field-Programmable 40 | Technology (FPT), December, 2014. 41 | http://www.ece.ubc.ca/~lemieux/publications/abdelhadi-fpt2014.pdf 42 | 43 | LICENSE: BSD 3-Clause ("BSD New" or "BSD Simplified") license. 44 | ####################################################################################### 45 | 46 | ####################################################################################### 47 | Files and directories in this package: 48 | ====================================== 49 | - README : This file! 50 | - LICENSE : BSD 3-Clause ("BSD New" or "BSD Simplified") license 51 | - fpt2014-paper.pdf : The 2014 Int'l Conf. on Field-Programmable Tech. (ICFPT) paper 52 | - fpt2014-slides.pdf: The 2014 Int'l Conf. on Field-Programmable Tech. (ICFPT) slides 53 | - sim : C-shell script: A run-in-batch simulation flow manager 54 | - syn : C-shell script: A run-in-batch synthesis flow manager 55 | - mux : C-shell script: Wide pipelined multiplexer generator 56 | - pe : C-shell script: Priority-encoder recursive generator 57 | - reduction : C-shell script: Wide pipelined reduction function generator 58 | - bcam.qpf : Quartus II project file 59 | - bcam.qsf : Quartus II settings file 60 | - bcam.sdc : Synopsys design constraints file; 61 | Design constraints and timing assignments 62 | - config.vh : Verilog: Generated by 'syn', contains design parameters 63 | - utils.vh : Verilog: Design pre-compile utilities 64 | - bcam_reg.v : Verilog: Register-based BCAM 65 | - bcam_bhv.v : Verilog: Behavioral description of BCAM 66 | - bcam_str.v : Verilog: Segmented Transposed-RAM BCAM 67 | - bcam_tb.v : Verilog: A Test-bench for BCAM 68 | - bcam_trc.v : Verilog: Brute-force/Transposed-RAM BCAM cascade 69 | - bcam_trs.v : Verilog: Brute-force/Transposed-RAM BCAM stage 70 | - bcam.v : Verilog: Binary Content Addressable Memory (BCAM) wrapper for: 71 | Behavioral (BHV), reg-based (REG), transposed-RAM stage (TRS), 72 | transposed-RAM cascade (TRC) & segmented transposed-RAM (STR) 73 | - dpram_be.v : Verilog: Dual-ported RAM with byte-enable 74 | - mwram_gen.v : Verilog: Generic mixed width RAM; not synthesizable with 75 | Altera's devices. May not be synthesizable with other vendors; 76 | Check your vendor's recommended HDL coding style 77 | - mwram_m20k.v : Verilog: Altera's M20K mixed width RAM 78 | - sbram_m20k.v : Verilog: Single-bit width RAM using Altera's M20K 79 | - spram.v : Verilog: Generic single port RAM 80 | - tdpram.v : Verilog: Generic true dual-ported RAM with data flow-through 81 | - trcam.v : Verilog: Transposed-RAM Stage CAM Core 82 | - sim.res : A list of simulation results, each run in a separate line, 83 | including all architectures 84 | - syn.res : A list of synthesis results, each run in a separate line, 85 | including: frequency, resources usage, and runtime 86 | - log/ : A directory containing Altera's logs and reports 87 | ####################################################################################### 88 | 89 | ####################################################################################### 90 | 2D BCAM module instantiation: 91 | =============================================== 92 | 93 | All *.v & *.vh files in this package should be copied into your work directory. 94 | Copy the following instantiation into your Verilog design, change parameters and 95 | connectivity to fit your design. 96 | 97 | // instantiate a 2D BCAM 98 | bcam #( 99 | // parameters 100 | .CAMD ( CAMD ), // CAM depth 101 | .CAMW ( CAMW ), // CAM/pattern width 102 | .SEGW ( SEGW ), // Segment width 103 | .INOM ( INOM ), // binary / Initial CAM with no match (has priority over IFILE) 104 | .REGW ( REGW ), // binary / register write inputs wEnb, wAddr, & wPatt? 105 | .REGM ( REGM ), // binary / register match input mPatt? 106 | .REGO ( REGO ), // binary / register outputs match & mAddr? 107 | .BRAM ( BRAM ), // BRAM type- "M20K":Altera's M20K; "GEN":generic 108 | .TYPE ( TYPE ) // implementation type: BHV, REG, TRAM, STRAM 109 | ) bcam_inst ( 110 | // ports 111 | .clk ( clk ), // clock / in 112 | .rst ( rst ), // global registers reset / in 113 | .wEnb ( wEnb ), // write enable / in 114 | .wAddr( wAddr ), // write address / in: [`log2(CAMD)-1:0] 115 | .wPatt( wPatt ), // write pattern / in : [ CAMW -1:0] 116 | .mPatt( mPatt ), // patern to match / in : [ CAMW -1:0] 117 | .match( match ), // match indicator / out: 118 | .mAddr( mAddr ) // matched address / out: [`log2(CAMD)-1:0] 119 | ); 120 | ####################################################################################### 121 | 122 | ####################################################################################### 123 | `sim`: A Run-in-batch Simulation Flow Manager 124 | ============================================= 125 | USAGE: 126 | ./sim <#Cycles> 127 | 128 | - Use a comma delimited list; no space; can be surrounded by brackets (), [], {}, <> 129 | - CAM depth, pattern width, segment width and cycles are positive integers 130 | 131 | EXAMPLES: 132 | ./sim 8192 9 8 1000000 133 | Simulate 1M cycles of a 8K lines CAM, 9 bits pattern width, 8 bits segments 134 | ./sim 2048,4096 8,9,10 8,16 1000000 135 | Simulate 1M cycles of CAMs with 2k or 4k lines, 8, 9, or 10 bits pattern, 136 | 8 or 16 bits segment. Total of 12 CAM 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 Synthesis Flow Manager 145 | ========================================== 146 | USAGE: 147 | ./syn \ 148 | 149 | 150 | - Use a comma delimited list; no space; can be surrounded by brackets (), [], {}, <> 151 | - CAM depth, pattern width and segment width are positive integers 152 | - Segments width list will be igonred for all architictures except of STR 153 | - Architecture is one of: REG, TRS, TRC, or STR 154 | - REG: Register-based Binary Content Addressable Memory 155 | - TRS: Transposed-RAM Binary Content Addressable Memory 156 | - TRC: Transposed-RAM Binary Content Addressable Memory 157 | - STR: Segmented Transposed-RAM Binary Content Addressable Memory 158 | - Bypassed? bypassed write to achieve match in the next cycle (Binary; 0/1) 159 | - Pipelined? bypassed BCAM version (Binary; 0/1) 160 | 161 | EXAMPLES: 162 | ./syn STR 8192 9 8 0 0 163 | Synthesis an unpipelined/unbypassed STR BCAM with 8K lines, 9 bits pattern 164 | width, and 8 bits segments width. 165 | ./syn REG,TRC 2048,4096 8,9,10 8 1 1 166 | Synthesis a pipelined/bypassed reg-based/TRC BCAM with 2k or 4k lines, 8, 9 167 | or 10 bits pattern. Segment width is ignored. Total of 6 CAM combinations. 168 | 169 | The following files and directories will be created after compilation: 170 | - syn.res : A list of results, each run in a separate line, including: 171 | frequency, resources usage, and runtime 172 | - log/ : Altera's logs and reports 173 | ##################################################################################### 174 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Modular SRAM-based 2D Hierarchical-Search ## 2 | ## Binary Content Addressable Memory (BCAM) ## 3 | --- 4 | ## Ameer M. S. Abdelhadi and Guy G. F. Lemieux ## 5 | ## The University of British Columbia (UBC) 2014 ## 6 | ## { ameer.abdelhadi; guy.lemieux } @ gmail.com ## 7 | --- 8 | 9 | A fully parameterized and generic Verilog implementation of the suggested modular SRAM-based 2D hierarchical-search Binary Content Addressable Memory (BCAM), together with other 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 is also provided. 10 | 11 | **LICENSE:** BSD 3-Clause ("BSD New" or "BSD Simplified") license. 12 | 13 | Please refer to the full paper for more information: 14 | 15 | **A. M.S. Abdelhadi and G. G.F. Lemieux, "Deep and Narrow Binary Content-Addressable Memories using FPGA-based BRAMs," International Conference on Field-Programmable Technology (FPT), December, 2014.** 16 | * **DOI:** http://dx.doi.org/10.1109/FPT.2014.7082808 17 | * **Paper:** https://www.ece.mcmaster.ca/~ameer/publications/Abdelhadi-Conference-2014Dec-FPT2014-DeepandNarrowBCAMs-full.pdf 18 | 19 | 20 | --- 21 | 22 | 23 | ## CAD Tools Requirements ## 24 | This project has been tested intensively using Altera's Design Suite version 14.0 Specifically: 25 | 1. Quartus II version 14.0 has been used to synthesize the Verilog implementation 26 | 2. ModelSim Altera Edition version 10.0d (modelsim\_ase) has been used to simulate the Verilog implementation. 27 | 28 | Furthermore, the run-in-batch synthesis and simulation flow managers have been implemented using C-Shell, hence a /bin/csh should be available in the machine 29 | 30 | 31 | --- 32 | 33 | 34 | ## Files and directories in this package ## 35 | 36 | * **README:** This file! 37 | * **LICENSE:** BSD 3-Clause ("BSD New" or "BSD Simplified") license 38 | * **fpt2014-paper.pdf:** The 2014 Int'l Conf. on Field-Programmable Tech. (ICFPT) paper 39 | * **fpt2014-slides.pdf:** The 2014 Int'l Conf. on Field-Programmable Tech. (ICFPT) slides 40 | * **sim:** C-shell script: A run-in-batch simulation flow manager 41 | * **syn:** C-shell script: A run-in-batch synthesis flow manager 42 | * **mux:** C-shell script: Wide pipelined multiplexer generator 43 | * **pe:** C-shell script: Priority-encoder recursive generator 44 | * **reduction:**C-shell script: Wide pipelined reduction function generator 45 | * **bcam.qpf:**Quartus II project file 46 | * **bcam.qsf:**Quartus II settings file 47 | * **bcam.sdc:**Synopsys design constraints file; Design constraints and timing assignments 48 | * **config.vh:**Verilog: Generated by 'syn', contains design parameters 49 | * **utils.vh:** Verilog: Design pre-compile utilities 50 | * **bcam_reg.v:** Verilog: Register-based BCAM 51 | * **bcam_bhv.v:** Verilog: Behavioral description of BCAM 52 | * **bcam_str.v:** Verilog: Segmented Transposed-RAM BCAM 53 | * **bcam_tb.v:** Verilog: A Test-bench for BCAM 54 | * **bcam_trc.v:** Verilog: Brute-force/Transposed-RAM BCAM cascade 55 | * **bcam_trs.v:** Verilog: Brute-force/Transposed-RAM BCAM stage 56 | * **bcam.v:** Verilog: Binary Content Addressable Memory (BCAM) wrapper for: Behavioral (BHV), reg-based (REG), transposed-RAM stage (TRS), transposed-RAM cascade (TRC) & segmented transposed-RAM (STR) 57 | * **dpram_be.v:** Verilog: Dual-ported RAM with byte-enable 58 | * **mwram_gen.v:** Verilog: Generic mixed width RAM; not synthesizable with Altera's devices. May not be synthesizable with other vendors; Check your vendor's recommended HDL coding style 59 | * **mwram_m20k.v:** Verilog: Altera's M20K mixed width RAM 60 | * **sbram_m20k.v:** Verilog: Single-bit width RAM using Altera's M20K 61 | * **spram.v:** Verilog: Generic single port RAM 62 | * **tdpram.v:** Verilog: Generic true dual-ported RAM with data flow-through 63 | * **trcam.v:** Verilog: Transposed-RAM Stage CAM Core 64 | * **sim.res:** A list of simulation results, each run in a separate line, including all architectures 65 | * **syn.res:** A list of synthesis results, each run in a separate line, including: frequency, resources usage, and runtime 66 | * **log/:** A directory containing Altera's logs and reports 67 | 68 | 69 | --- 70 | 71 | 72 | ## 2D BCAM module instantiation ## 73 | All **.v &**.vh files in this package should be copied into your work directory. Copy the following instantiation into your Verilog design, change parameters and connectivity to fit your design. 74 | 75 | ``` 76 | // instantiate a 2D BCAM 77 | bcam #( 78 | // parameters 79 | .CAMD ( CAMD ), // CAM depth 80 | .CAMW ( CAMW ), // CAM/pattern width 81 | .SEGW ( SEGW ), // Segment width 82 | .INOM ( INOM ), // binary / Initial CAM with no match (has priority over IFILE) 83 | .REGW ( REGW ), // binary / register write inputs wEnb, wAddr, & wPatt? 84 | .REGM ( REGM ), // binary / register match input mPatt? 85 | .REGO ( REGO ), // binary / register outputs match & mAddr? 86 | .BRAM ( BRAM ), // BRAM type- "M20K":Altera's M20K; "GEN":generic 87 | .TYPE ( TYPE ) // implementation type: BHV, REG, TRAM, STRAM 88 | ) bcam_inst ( 89 | // ports 90 | .clk ( clk ), // clock / in 91 | .rst ( rst ), // global registers reset / in 92 | .wEnb ( wEnb ), // write enable / in 93 | .wAddr( wAddr ), // write address / in: [`log2(CAMD)-1:0] 94 | .wPatt( wPatt ), // write pattern / in : [ CAMW -1:0] 95 | .mPatt( mPatt ), // patern to match / in : [ CAMW -1:0] 96 | .match( match ), // match indicator / out: 97 | .mAddr( mAddr ) // matched address / out: [`log2(CAMD)-1:0] 98 | ); 99 | ``` 100 | 101 | 102 | --- 103 | 104 | 105 | ## `sim`: A Run-in-batch Simulation Flow Manager ## 106 | 107 | ### USAGE: ### 108 | 109 | `./sim <#Cycles>` 110 | 111 | * Use a comma delimited list; no space; can be surrounded by brackets (), [], {}, <> 112 | * CAM depth, pattern width, segment width and cycles are positive integers 113 | 114 | ### EXAMPLES: ### 115 | 116 | * `./sim 8192 9 8 1000000` 117 | * Simulate 1M cycles of a 8K lines CAM, 9 bits pattern width, 8 bits segments 118 | * `./sim 2048,4096 8,9,10 8,16 1000000` 119 | * Simulate 1M cycles of CAMs with 2k or 4k lines, 8, 9, or 10 bits pattern, 8 or 16 bits segment. Total of 12 CAM combinations 120 | 121 | The following files and directories will be created after simulation : 122 | * sim.res : A list of simulation results, each run in a separate line, including all design styles. 123 | 124 | 125 | --- 126 | 127 | 128 | ## `syn`: A Run-in-batch Synthesis Flow Manager ## 129 | 130 | ### USAGE: ### 131 | 132 | `./syn ` 133 | 134 | * Use a comma delimited list; no space; can be surrounded by brackets (), [], {}, <> 135 | * CAM depth, pattern width and segment width are positive integers 136 | * Segments width list will be igonred for all architictures except of STR 137 | * Architecture is one of: REG, TRS, TRC, or STR 138 | * REG: Register-based Binary Content Addressable Memory 139 | * TRS: Transposed-RAM Binary Content Addressable Memory 140 | * TRC: Transposed-RAM Binary Content Addressable Memory 141 | * STR: Segmented Transposed-RAM Binary Content Addressable Memory 142 | * Bypassed? bypassed write to achieve match in the next cycle (Binary; 0/1) 143 | * Pipelined? bypassed BCAM version (Binary; 0/1) 144 | 145 | ### EXAMPLES: ### 146 | 147 | * `./syn STR 8192 9 8 0 0` 148 | * Synthesis an unpipelined/unbypassed STR BCAM with 8K lines, 9 bits pattern width, and 8 bits segments width. 149 | * `./syn REG,TRC 2048,4096 8,9,10 8 1 1` 150 | * Synthesis a pipelined/bypassed reg-based/TRC BCAM with 2k or 4k lines, 8, 9 or 10 bits pattern. Segment width is ignored. Total of 6 CAM combinations. 151 | 152 | The following files and directories will be created after compilation: 153 | * syn.res : A list of results, each run in a separate line, including: frequency, resources usage, and runtime 154 | * log/ : Altera's logs and reports 155 | -------------------------------------------------------------------------------- /bcam.qpf: -------------------------------------------------------------------------------- 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 | ## bcam.qpf: Quartus II project file ## 31 | ## ## 32 | ## Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) ## 33 | ## SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 ## 34 | #################################################################################### 35 | 36 | 37 | QUARTUS_VERSION = "12.0" 38 | DATE = "18:35:54 March 21, 2014" 39 | 40 | # Revisions 41 | 42 | PROJECT_REVISION = "bcam" 43 | -------------------------------------------------------------------------------- /bcam.qsf: -------------------------------------------------------------------------------- 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 | ## bcam.qsf: Quartus II settings file ## 31 | ## ## 32 | ## Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) ## 33 | ## SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 ## 34 | #################################################################################### 35 | 36 | # Family and device settings 37 | set_global_assignment -name FAMILY "Stratix V" 38 | set_global_assignment -name DEVICE 5SGXMA7N1F45C1 39 | 40 | # The name of the top-level design entity for this project. 41 | # This name is case sensitive and must exactly match the entity name in the design file 42 | set_global_assignment -name TOP_LEVEL_ENTITY bcam 43 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1 44 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:35:09 APRIL 14, 2014" 45 | set_global_assignment -name LAST_QUARTUS_VERSION 13.1 46 | 47 | # design files to be included in this project 48 | set_global_assignment -name VERILOG_INCLUDE_FILE config.vh 49 | set_global_assignment -name VERILOG_INCLUDE_FILE utils.vh 50 | set_global_assignment -name VERILOG_FILE trcam.v 51 | set_global_assignment -name VERILOG_FILE tdpram.v 52 | set_global_assignment -name VERILOG_FILE spram.v 53 | set_global_assignment -name VERILOG_FILE mwram_m20k.v 54 | set_global_assignment -name VERILOG_FILE sbram_m20k.v 55 | set_global_assignment -name VERILOG_FILE dpram_be.v 56 | set_global_assignment -name VERILOG_FILE bcam.v 57 | set_global_assignment -name VERILOG_FILE bcam_trs.v 58 | set_global_assignment -name VERILOG_FILE bcam_trc.v 59 | set_global_assignment -name VERILOG_FILE bcam_str.v 60 | set_global_assignment -name VERILOG_FILE bcam_reg.v 61 | set_global_assignment -name VERILOG_FILE pe_camd.v 62 | set_global_assignment -name VERILOG_FILE pe_nseg.v 63 | set_global_assignment -name VERILOG_FILE pe_segw.v 64 | set_global_assignment -name VERILOG_FILE reduction_or.v 65 | set_global_assignment -name VERILOG_FILE mux_data2rmv.v 66 | 67 | set_global_assignment -name SDC_FILE bcam.sdc 68 | 69 | # Operating temperature conditions 70 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 71 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 72 | 73 | # The Quartus II software uses the ERROR_CHECK_FREQUENCY_DIVISOR value in the CRC block in the compilation. 74 | # Make sure the ERROR_CHECK_FREQUENCY_DIVISOR value in the CRC block and the in the QSF have the same value. 75 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256 76 | 77 | # EDA tools used with the Quartus II software to develop your project 78 | set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (Verilog)" 79 | set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "VERILOG HDL" -section_id eda_simulation 80 | 81 | ################################# 82 | ## Compilation Process Options ## 83 | ################################# 84 | 85 | # Parallel compilation: use all available processors 86 | # Specifies the maximum number of processors allocated for parallel compilation on a single machine. 87 | # For parallel compilation you can use all available processors on your machine, or specify the number of processors you want to use. 88 | # For example, if you have a quad-core processor machine and want to leave one processor free for other tasks, you specify '3' as the setting of this option. 89 | # A setting of '1' disables parallel compilation. 90 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 91 | 92 | # Use smart compilation to help future compilations run faster 93 | set_global_assignment -name SMART_RECOMPILE ON 94 | 95 | # Allows the RTL Viewer to process the schematic during design compilation. 96 | # Allows to open the RTL Viewer after the Analysis & Synthesis portion of design compilation completes, rather than waiting for the full compilation to complete. 97 | set_global_assignment -name FLOW_ENABLE_RTL_VIEWER ON 98 | 99 | # Directs the TimeQuest Timing Analyzer to perform multicorner timing analysis, which analyzes the design against best-case and worst-case operating conditions. 100 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 101 | 102 | # Specifies the directory in which to save all project output files such as the Text-Format Report Files (.rpt) and Equation Files (.eqn). 103 | # By default, all project output files are saved in the project directory. 104 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 105 | 106 | ##################################### 107 | ## Physical Synthesis Optimization ## 108 | ##################################### 109 | 110 | ## Optimization for performance 111 | 112 | # Perform physical synthesis optimizations on combinational logic during synthesis and fitting to increase circuit performance. 113 | # >>> Run-time increases if enabled 114 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 115 | 116 | # Allows register retiming, during synthesis and fitting to increase circuit performance. 117 | # >>> Registers consumption may increase due to retiming 118 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 119 | 120 | # Effort level: FAST, NORMAL, or EXTRA. 121 | # Specifies the amount of effort, in terms of compile time, physical synthesis should use. 122 | # Compared to the Default setting, a setting of Extra will use extra compile time to try to gain extra circuit performance. 123 | # Conversely, a setting of Fast will use less compile time but may reduce the performance gain that physical synthesis is able to achieve. 124 | set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA 125 | 126 | ## Fitter netlist optimization 127 | 128 | # Specifies that Quartus II should perform automatic insertion of pipeline stages for asynchronous clear and asynchronous load signals during fitting to increase circuit performance. 129 | # This option is useful for asynchronous signals that are failing recovery and removal timing because they feed registers using a high-speed clock. 130 | set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON 131 | 132 | # Specifies that the Fitter should perform physical synthesis optimizations on registers, specifically allowing register duplication, during fitting to increase circuit performance. 133 | # >>> Registers consumption increases, check if affects retiming 134 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 135 | 136 | 137 | ## optimization for fitting 138 | 139 | # Specifies that the Fitter should perform physical synthesis optimizations on combinational logic during fitting to achieve a fit. 140 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON 141 | 142 | ################################### 143 | ## Analysis & Synthesis Settings ## 144 | ################################### 145 | 146 | # Optimization Technique: SPEED, BALANCED, or AREA 147 | # Specifies the overall optimization goal for Analysis & Synthesis: attempt to maximize performance, minimize logic usage, or balance high performance with minimal logic usage. 148 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 149 | 150 | # Allows synthesis to use timing information during synthesis to better optimize the design. 151 | set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON 152 | 153 | # Iteration limit for constant Verilog loops (e.g. for loops) 154 | # Defines the iteration limit for Verilog loops with loop conditions that evaluate to compile-time constants on each loop iteration. 155 | # This limit exists primarily to identify potential infinite loops before they exhaust memory or trap the software in an actual infinite loop. 156 | set_global_assignment -name VERILOG_CONSTANT_LOOP_LIMIT 1048576 157 | 158 | # Iteration limit for non-constant Verilog loops (e.g. while loops) 159 | # Defines the iteration limit for Verilog loops with loop conditions that do not evaluate to compile-time constants on each loop iteration. 160 | # This limit exists primarily to identify potential infinite loops before they exhaust memory or trap the software in an actual infinite loop. 161 | set_global_assignment -name VERILOG_NON_CONSTANT_LOOP_LIMIT 1048576 162 | 163 | # Removes redundant LCELL primitives or WYSIWYG primitives. 164 | # Turning this option on optimizes a circuit for area and speed. 165 | # This option is ignored if it is applied to anything other than a design entity. 166 | set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON 167 | 168 | # Removes a register if it is identical to another register. 169 | # If two registers generate the same logic, the second one will be deleted and the first one will be made to fan out to the second one's destinations. 170 | # Also, if the deleted register has different logic option assignments, they will be ignored. 171 | # This option is useful if you wish to prevent the Compiler from removing duplicate registers that you have used deliberately. You can do this by setting the option to Off. 172 | # This option is ignored if it is applied to anything other than an individual register or a design entity containing registers. 173 | set_global_assignment -name REMOVE_DUPLICATE_REGISTERS ON 174 | 175 | ##################### 176 | ## Fitter Settings ## 177 | ##################### 178 | 179 | # Allows the Fitter to optimize hold time by adding delay to the appropriate paths. 180 | # The Optimize Timing option must be turned on in order for this option to work. 181 | # If you are using the TimeQuest Timing Analyzer, and specify the I/O paths and Minimum tpd Paths setting, all assignments involving I/O pins are optimized. 182 | # Specifying the All Paths setting directs the Fitter to optimize the hold time of all paths. 183 | # Turning off this option directs the Fitter not to optimize the hold time of any paths. 184 | # Use: "ALL PATHS", "IO PATHS AND MINIMUM TPD PATHS", or OFF 185 | #set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF 186 | 187 | # Controls whether the Fitter optimizes a design to meet timing requirements at all process corners and operating conditions. 188 | # The Optimize Timing logic option must be enabled for this option to work. 189 | # When this setting is turned off, designs are optimized to meet timing only at the slow timing process corner and operating condition. 190 | # When this option is turned on, designs are optimized to meet timing at all corners and operating conditions; 191 | # as a result, turning on this option helps create a design implementation that is more robust across process, temperature, and voltage variations. 192 | set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON 193 | 194 | # Controls the fitter's trade-off between performance and compilation speed. 195 | # Auto Fit adjusts the fitter optimization effort to minimize compilation time, while still achieving the design timing requirements. 196 | # The FITTER_AUTO_EFFORT_DESIRED_SLACK_MARGIN option can be used to request that Auto Fit apply sufficient optimization effort to achieve additional timing margin. 197 | # Standard Fit will use maximum effort regardless of the design's requirements, leading to higher compilation time and more margin on easier designs. 198 | # For difficult designs, Auto Fit and Standard Fit will both use maximum effort. 199 | # Fast Fit will decrease optimization effort to reduce compilation time, which may degrade design performance. 200 | #set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 201 | 202 | # Router timing optimization level: MAXIMUM, MINIMUM, or NORMAL (default) 203 | # Controls how aggressively the router tries to meet timing requirements. 204 | # Setting this option to Maximum can increase design speed slightly, at the cost of increased compile time. 205 | # Setting this option to Minimum can reduce compile time, at the cost of slightly reduced design speed. 206 | #set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL MAXIMUM 207 | 208 | ############################### 209 | ## TimeQuest Timing Analyzer ## 210 | ############################### 211 | 212 | # Directs the TimeQuest Timing Analyzer to report the worst-case path per clock domain and analysis. 213 | set_global_assignment -name TIMEQUEST_DO_REPORT_TIMING ON 214 | 215 | # Directs the TimeQuest Timing Analyzer to remove common clock path pessimism (CCPP) during slack computation. 216 | set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON 217 | 218 | -------------------------------------------------------------------------------- /bcam.sdc: -------------------------------------------------------------------------------- 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 | ## bcam.sdc: Synopsys design constraints file ## 31 | ## Design constraints and timing assignments ## 32 | ## ## 33 | ## Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) ## 34 | ## SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 ## 35 | #################################################################################### 36 | 37 | # Clock constraints 38 | create_clock -name "clk" -period 1.000ns [get_ports {clk}] 39 | 40 | # Automatically constrain PLL and other generated clocks 41 | derive_pll_clocks -create_base_clocks 42 | 43 | # Automatically calculate clock uncertainty to jitter and other effects. 44 | derive_clock_uncertainty 45 | 46 | # tsu/th constraints 47 | #set_input_delay -clock "clk" -max 0.8ns [get_ports {wAddr}] 48 | #set_input_delay -clock "clk" -min 0.100ns [get_ports {wAddr}] 49 | 50 | 51 | # tco constraints 52 | #set_output_delay -clock "clk" -max 0.8ns [get_ports {mAddr}] 53 | #set_output_delay -clock "clk" -min -0.100ns [get_ports {mAddr}] 54 | 55 | # disable input/output combinatorial timing (all ports are registered) 56 | set_disable_timing -from [all_inputs] * 57 | set_disable_timing -to [all_outputs] * 58 | -------------------------------------------------------------------------------- /bcam.v: -------------------------------------------------------------------------------- 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 | // bcam.v: Binary Content Addressable Memory (BCAM) wrapper for: // 29 | // Behavioral (BHV), register-based (REG), transposed-RAM stage (TRS) // 30 | // ,transposed-RAM cascade (TRC) & segmented transposed-RAM (STR) // 31 | // // 32 | // Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 33 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 34 | //////////////////////////////////////////////////////////////////////////////////// 35 | 36 | `include "utils.vh" 37 | 38 | `ifndef SIM 39 | // configure architectural parameters for synthesis 40 | // to define CAMD, CAMW, SEGW, and TYPE 41 | `include "config.vh" 42 | `endif 43 | 44 | `ifndef TYPE 45 | `define TYPE "" 46 | `endif 47 | 48 | `ifndef PIPE 49 | `define PIPE 0 50 | `endif 51 | 52 | `ifndef BYPS 53 | `define BYPS 1 54 | `endif 55 | 56 | module bcam 57 | #( parameter CAMD = `CAMD , // CAM depth / a multiply of SEGW 58 | parameter CAMW = `CAMW , // CAM/pattern width 59 | parameter SEGW = `SEGW , // Segment width / STRAM only 60 | parameter BYPS = `BYPS , // Bypassed? (binary; 0 or 1) 61 | parameter PIPE = `PIPE , // Pipelined? (binary; 0 or 1) 62 | parameter INOM = 1 , // binary / Initial CAM with no match 63 | parameter REGW = 1 , // binary / register write inputs wEnb, wAddr, & wPatt? 64 | parameter REGM = 1 , // binary / register match input mPatt? 65 | parameter REGO = 1 , // binary / register outputs match & mAddr? 66 | parameter BRAM = "M20K", // BRAM type- "M20K":Altera's M20K; "GEN":generic 67 | parameter TYPE = `TYPE ) // implementation type: BHV, REG, TRS, TRC, & STR 68 | ( input clk , // clock 69 | input rst , // global registers reset 70 | input wEnb , // write enable 71 | input [`log2(CAMD)-1:0] wAddr , // write address 72 | input [ CAMW -1:0] wPatt , // write patterns 73 | input [ CAMW -1:0] mPatt , // patern to match 74 | output match , // match indicator 75 | output [`log2(CAMD)-1:0] mAddr ); // matched address 76 | 77 | localparam ADDRW = `log2(CAMD); // address width 78 | 79 | // register inputs 1 80 | reg wEnbR; 81 | reg [ADDRW-1:0] wAddrR; 82 | reg [CAMW -1:0] wPattR,mPattR; 83 | always @(posedge clk, posedge rst) 84 | if (rst) {wEnbR,wAddrR,wPattR,mPattR} <= {(1 +ADDRW+CAMW +CAMW ){1'b0}}; 85 | else {wEnbR,wAddrR,wPattR,mPattR} <= { wEnb,wAddr,wPatt,mPatt }; 86 | 87 | // register inputs 2 88 | reg wEnbRR; 89 | reg [ADDRW-1:0] wAddrRR; 90 | reg [CAMW -1:0] wPattRR,mPattRR; 91 | always @(posedge clk, posedge rst) 92 | if (rst) {wEnbRR,wAddrRR,wPattRR,mPattRR} <= {(1 +ADDRW +CAMW +CAMW ){1'b0}}; 93 | else {wEnbRR,wAddrRR,wPattRR,mPattRR} <= { wEnbR,wAddrR,wPattR,mPattR }; 94 | 95 | // assign inputs 96 | wire wEnbI = PIPE ? wEnbRR : ( REGW ? wEnbR : wEnb ); 97 | wire [ADDRW-1:0] wAddrI = PIPE ? wAddrRR : ( REGW ? wAddrR : wAddr ); 98 | wire [CAMW -1:0] wPattI = PIPE ? wPattRR : ( REGW ? wPattR : wPatt ); 99 | wire [CAMW -1:0] mPattI = PIPE ? mPattRR : ( REGM ? mPattR : mPatt ); 100 | 101 | // generate and instantiate BCAM with specific implementation 102 | wire matchI; 103 | wire [ADDRW-1:0] mAddrI; 104 | generate 105 | if (TYPE=="BHV") begin 106 | // instantiate behavioral BCAM 107 | bcam_bhv #( .CAMD ( CAMD ), // CAM depth 108 | .CAMW ( CAMW ), // CAM/pattern width 109 | .INOM ( INOM )) // binary / Initial CAM with no match (has priority over IFILE) 110 | bcam_bhv_i ( .clk ( clk ), // clock 111 | .rst ( rst ), // global registers reset 112 | .wEnb ( wEnbI ), // write enable 113 | .wAddr( wAddrI ), // write address 114 | .wPatt( wPattI ), // write pattern 115 | .mPatt( mPattI ), // patern to match 116 | .match( matchI ), // match indicator 117 | .mAddr( mAddrI )); // matched address 118 | end 119 | else if (TYPE=="REG") begin 120 | // instantiate register-based BCAM 121 | bcam_reg #( .CAMD ( CAMD ), // CAM depth 122 | .CAMW ( CAMW ), // CAM/pattern width 123 | .PIPE ( PIPE ), // Pipelined? (binary; 0 or 1) 124 | .INOM ( INOM )) // binary / Initial CAM with no match (has priority over IFILE) 125 | bcam_reg_i ( .clk ( clk ), // clock 126 | .rst ( rst ), // global registers reset 127 | .wEnb ( wEnbI ), // write enable 128 | .wAddr( wAddrI ), // write address 129 | .wPatt( wPattI ), // write pattern 130 | .mPatt( mPattI ), // patern to match 131 | .match( matchI ), // match indicator 132 | .mAddr( mAddrI )); // matched address 133 | end 134 | else if (TYPE=="TRS") begin 135 | // instantiate transposed-RAM stage BCAM (TRS) 136 | bcam_trc #( .CAMD ( CAMD ), // CAM depth 137 | .CAMW ( CAMW ), // CAM/pattern width 138 | .STGW ( 524288 ), // maximum stage width (9 for M20k; infinity for uncascaded) - allow STGW+1 for last stage if required 139 | .BYPS ( BYPS ), // Bypassed? (binary; 0 or 1) 140 | .PIPE ( PIPE ), // Pipelined? (binary; 0 or 1) 141 | .INOM ( INOM ), // binary / Initial CAM with no match (has priority over IFILE) 142 | .BRAM ( BRAM )) // BRAM type- "M20K":Altera's M20K; "GEN":generic 143 | bcam_trs_i ( .clk ( clk ), // clock 144 | .rst ( rst ), // global registers reset 145 | .wEnb ( wEnbI ), // write enable 146 | .wAddr( wAddrI ), // write address 147 | .wPatt( wPattI ), // write pattern 148 | .mPatt( mPattI ), // patern to match 149 | .match( matchI ), // match indicator 150 | .mAddr( mAddrI )); // matched address 151 | end 152 | else if (TYPE=="TRC") begin 153 | // instantiate transposed-RAM cascade BCAM (TRC) 154 | bcam_trc #( .CAMD ( CAMD ), // CAM depth 155 | .CAMW ( CAMW ), // CAM/pattern width 156 | .STGW ( 9 ), // maximum stage width (9 for M20k; infinity for uncascaded) - allow STGW+1 for last stage if required 157 | .BYPS ( BYPS ), // Bypassed? (binary; 0 or 1) 158 | .PIPE ( PIPE ), // Pipelined? (binary; 0 or 1) 159 | .INOM ( INOM ), // binary / Initial CAM with no match (has priority over IFILE) 160 | .BRAM ( BRAM )) // BRAM type- "M20K":Altera's M20K; "GEN":generic 161 | bcam_trc_i ( .clk ( clk ), // clock 162 | .rst ( rst ), // global registers reset 163 | .wEnb ( wEnbI ), // write enable 164 | .wAddr( wAddrI ), // write address 165 | .wPatt( wPattI ), // write pattern 166 | .mPatt( mPattI ), // patern to match 167 | .match( matchI ), // match indicator 168 | .mAddr( mAddrI )); // matched address 169 | end 170 | else begin // default: STRAM 171 | // instantiate segmented transposed-RAM BCAM (STRAM) 172 | bcam_str #( .CAMD ( CAMD ), // CAM depth 173 | .CAMW ( CAMW ), // CAM/pattern width 174 | .SEGW ( SEGW ), // Segment width 175 | .BYPS ( BYPS ), // Bypassed? (binary; 0 or 1) 176 | .PIPE ( PIPE ), // Pipelined? (binary; 0 or 1) 177 | .INOM ( INOM ), // binary / Initial CAM with no match (has priority over IFILE) 178 | .BRAM ( BRAM )) // BRAM type- "M20K":Altera's M20K; "GEN":generic 179 | bcam_str_i ( .clk ( clk ), // clock 180 | .rst ( rst ), // global registers reset 181 | .wEnb ( wEnbI ), // write enable 182 | .wAddr( wAddrI ), // write address 183 | .wPatt( wPattI ), // write pattern 184 | .mPatt( mPattI ), // patern to match 185 | .match( matchI ), // match indicator 186 | .mAddr( mAddrI )); // matched address 187 | end 188 | endgenerate 189 | 190 | // register outputs 1 191 | reg matchIR; 192 | reg [ADDRW-1:0] mAddrIR; 193 | always @(posedge clk, posedge rst) 194 | if (rst) {matchIR,mAddrIR} <= {(1 +ADDRW ){1'b0}}; 195 | else {matchIR,mAddrIR} <= { matchI,mAddrI }; 196 | 197 | // register outputs 2 198 | reg matchIRR; 199 | reg [ADDRW-1:0] mAddrIRR; 200 | always @(posedge clk, posedge rst) 201 | if (rst) {matchIRR,mAddrIRR} <= {(1 +ADDRW ){1'b0}}; 202 | else {matchIRR,mAddrIRR} <= { matchIR,mAddrIR }; 203 | 204 | // assign outputs 205 | assign match = PIPE ? matchIRR : ( REGO ? matchIR : matchI); 206 | assign mAddr = PIPE ? mAddrIRR : ( REGO ? mAddrIR : mAddrI); 207 | 208 | endmodule 209 | 210 | -------------------------------------------------------------------------------- /bcam_bhv.v: -------------------------------------------------------------------------------- 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 | // bcam_bhv.v: Behavioral description of Binary Content Addressasble Memory (BCAM)// 29 | // // 30 | // Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `include "utils.vh" 35 | 36 | module bcam_bhv 37 | #( parameter CAMD = 512, // CAM depth 38 | parameter CAMW = 32 , // CAM/pattern width 39 | parameter INOM = 1 ) // binary / Initial CAM with no match (has priority over IFILE) 40 | ( input clk , // clock 41 | input rst , // global registers reset 42 | input wEnb , // write enable 43 | input [`log2(CAMD)-1:0] wAddr , // write address 44 | input [ CAMW -1:0] wPatt , // write pattern 45 | input [ CAMW -1:0] mPatt , // patern to match 46 | output reg match , // match indicator 47 | output reg [`log2(CAMD)-1:0] mAddr ); // matched address 48 | 49 | // assign memory array 50 | reg [CAMW-1:0] mem [0:CAMD-1]; 51 | 52 | // valid bit 53 | reg [CAMD-1:0] vld; 54 | 55 | // initialize memory, with zeros if INOM or file if IFILE. 56 | integer i; 57 | initial 58 | if (INOM) 59 | for (i=0; i0) $write("x"); else $write("-"); 155 | end 156 | failCntTmp = 0; 157 | end 158 | // finish if terminate on any failure 159 | if (TERFAIL && (!pass[ALL])) begin 160 | $write("*** Simulation terminated due to output mismatch\n"); 161 | $fclose(rep_fd); 162 | $finish; 163 | end 164 | if (cycc==CYCC) begin 165 | // write to report file 166 | $fwrite(rep_fd,"%-7d %-7d %-7d %-7d %-5d %-5d %-5d %-5d\n",CAMD,CAMW,SEGW,CYCC,failCntReg,failCntTRS,failCntTRC,failCntSTR); 167 | // write to STDOUT 168 | $write("\n*** Simulation terminated after %0d cycles with %0d failures. Results:\n",CYCC,failCntAll); 169 | $write("REG = %-5d mismatches\n",failCntReg); 170 | $write("TRS = %-5d mismatches\n",failCntTRS); 171 | $write("TRC = %-5d mismatches\n",failCntTRC); 172 | $write("STR = %-5d mismatches\n",failCntSTR); 173 | $fclose(rep_fd); 174 | $finish; 175 | end 176 | cycc=cycc+1; 177 | end 178 | end 179 | 180 | // Behavioral BCAM 181 | bcam #( .CAMD ( CAMD ), // CAM depth 182 | .CAMW ( CAMW ), // CAM/pattern width 183 | .INOM ( 1 ), // binary / Initial CAM with no match (has priority over IFILE) 184 | .REGW ( 1 ), // binary / register write inputs wEnb, wAddr, & wPatt? 185 | .REGM ( 0 ), // binary / register match input mPatt? 186 | .REGO ( 1 ), // binary / register outputs match & mAddr? 187 | .TYPE ( "BHV" )) // implementation type: BHV, REG, TRAM, STRAM 188 | bcam_bhv_i ( .clk ( clk ), // clock 189 | .rst ( rst ), // global registers reset 190 | .wEnb ( wEnb ), // write enable 191 | .wAddr( wAddr ), // write address 192 | .wPatt( wPatt ), // write pattern 193 | .mPatt( mPatt ), // patern to match 194 | .match( matchBhv ), // match indicator 195 | .mAddr( mAddrBhv )); // matched address 196 | 197 | // Register-based BCAM 198 | bcam #( .CAMD ( CAMD ), // CAM depth 199 | .CAMW ( CAMW ), // CAM/pattern width 200 | .INOM ( 1 ), // binary / Initial CAM with no match (has priority over IFILE) 201 | .REGW ( 0 ), // binary / register write inputs wEnb, wAddr, & wPatt? 202 | .REGM ( 0 ), // binary / register match input mPatt? 203 | .REGO ( 1 ), // binary / register outputs match & mAddr? 204 | .TYPE ( "REG" )) // implementation type: BHV, REG, TRAM, STRAM 205 | bcam_reg_i ( .clk ( clk ), // clock 206 | .rst ( rst ), // global registers reset 207 | .wEnb ( wEnb ), // write enable 208 | .wAddr( wAddr ), // write address / [`log2(CAMD)-1:0] 209 | .wPatt( wPatt ), // write pattern / [ CAMW -1:0] 210 | .mPatt( mPatt ), // patern to match / [ CAMW -1:0] 211 | .match( matchReg ), // match indicator 212 | .mAddr( mAddrReg )); // matched address / [`log2(CAMD)-1:0] 213 | 214 | // Transposed-RAM stage (Brute-Force) BCAM 215 | bcam #( .CAMD ( CAMD ), // CAM depth 216 | .CAMW ( CAMW ), // CAM/pattern width 217 | .INOM ( 1 ), // binary / Initial CAM with no match (has priority over IFILE) 218 | .REGW ( 0 ), // binary / register write inputs wEnb, wAddr, & wPatt? 219 | .REGM ( 0 ), // binary / register match input mPatt? 220 | .REGO ( 1 ), // binary / register outputs match & mAddr? 221 | .BRAM ( "M20K" ), // BRAM type- "M20K":Altera's M20K; "GEN":generic 222 | .TYPE ( "TRS" )) // implementation type: BHV, REG, TRAM, STRAM 223 | bcam_trs_i ( .clk ( clk ), // clock 224 | .rst ( rst ), // global registers reset 225 | .wEnb ( wEnb ), // write enable 226 | .wAddr( wAddr ), // write address / [`log2(CAMD)-1:0] 227 | .wPatt( wPatt ), // write pattern / [ CAMW -1:0] 228 | .mPatt( mPatt ), // patern to match / [ CAMW -1:0] 229 | .match( matchTRS ), // match indicator 230 | .mAddr( mAddrTRS )); // matched address / [`log2(CAMD)-1:0] 231 | 232 | // Transposed-RAM cascade (Brute-Force) BCAM 233 | bcam #( .CAMD ( CAMD ), // CAM depth 234 | .CAMW ( CAMW ), // CAM/pattern width 235 | .INOM ( 1 ), // binary / Initial CAM with no match (has priority over IFILE) 236 | .REGW ( 0 ), // binary / register write inputs wEnb, wAddr, & wPatt? 237 | .REGM ( 0 ), // binary / register match input mPatt? 238 | .REGO ( 1 ), // binary / register outputs match & mAddr? 239 | .BRAM ( "M20K" ), // BRAM type- "M20K":Altera's M20K; "GEN":generic 240 | .TYPE ( "TRC" )) // implementation type: BHV, REG, TRAM, STRAM 241 | bcam_trc_i ( .clk ( clk ), // clock 242 | .rst ( rst ), // global registers reset 243 | .wEnb ( wEnb ), // write enable 244 | .wAddr( wAddr ), // write address / [`log2(CAMD)-1:0] 245 | .wPatt( wPatt ), // write pattern / [ CAMW -1:0] 246 | .mPatt( mPatt ), // patern to match / [ CAMW -1:0] 247 | .match( matchTRC ), // match indicator 248 | .mAddr( mAddrTRC )); // matched address / [`log2(CAMD)-1:0] 249 | 250 | // Segmented Transposed-RAM BCAM 251 | bcam #( .CAMD ( CAMD ), // CAM depth 252 | .CAMW ( CAMW ), // CAM/pattern width 253 | .SEGW ( SEGW ), // Segment width 254 | .INOM ( 1 ), // binary / Initial CAM with no match (has priority over IFILE) 255 | .REGW ( 0 ), // binary / register write inputs wEnb, wAddr, & wPatt? 256 | .REGM ( 0 ), // binary / register match input mPatt? 257 | .REGO ( 0 ), // binary / register outputs match & mAddr? 258 | .BRAM ( "M20K" ), // BRAM type- "M20K":Altera's M20K; "GEN":generic 259 | .TYPE ( "STRAM" )) // implementation type: BHV, REG, TRAM, STRAM 260 | bcam_str_i ( .clk ( clk ), // clock 261 | .rst ( rst ), // global registers reset 262 | .wEnb ( wEnb ), // write enable 263 | .wAddr( wAddr ), // write address / [`log2(CAMD)-1:0] 264 | .wPatt( wPatt ), // write pattern / [ CAMW -1:0] 265 | .mPatt( mPatt ), // patern to match / [ CAMW -1:0] 266 | .match( matchSTR ), // match indicator 267 | .mAddr( mAddrSTR )); // matched address / [`log2(CAMD)-1:0] 268 | 269 | // Register outputs / second stage 270 | always @(posedge clk, posedge rst) 271 | if (rst) {mAddrRegR,matchRegR} <= {(ADDRW +1 ){1'b0}}; 272 | else {mAddrRegR,matchRegR} <= { mAddrReg,matchReg }; 273 | 274 | endmodule 275 | -------------------------------------------------------------------------------- /bcam_trc.v: -------------------------------------------------------------------------------- 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 | // bcam_trc.v: // 29 | // Brute-force/Transposed-RAM Binary Content Addressasble Memory (BCAM) cascade // 30 | // // 31 | // Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 32 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 33 | //////////////////////////////////////////////////////////////////////////////////// 34 | 35 | `include "utils.vh" 36 | 37 | module bcam_trc 38 | #( parameter CAMD = 128 , // CAM depth 39 | parameter CAMW = 9 , // CAM/pattern width 40 | parameter STGW = 9 , // maximum stage width (9 for M20k; infinity for uncascaded) - allow STGW+1 for last stage if required 41 | parameter BYPS = 1 , // Bypassed? (binary; 0 or 1) 42 | parameter PIPE = 0 , // Pipelined? (binary; 0 or 1) 43 | parameter INOM = 1 , // binary / Initial CAM with no match 44 | parameter BRAM = "M20K") // BRAM type- "M20K":Altera's M20K; "GEN":generic 45 | ( input clk , // clock 46 | input rst , // global registers reset 47 | input wEnb , // write enable 48 | input [`log2(CAMD)-1:0] wAddr , // write address 49 | input [ CAMW -1:0] wPatt , // write pattern 50 | input [ CAMW -1:0] mPatt , // patern to match 51 | output match , // match indicator 52 | output [`log2(CAMD)-1:0] mAddr ); // matched address 53 | 54 | /////////////////////////////////////////////////////////////////////////////// 55 | 56 | // Stage parameters 57 | localparam nSTG = CAMW/STGW+((CAMW%STGW)>1) ; // number of stage 58 | localparam LSTGW = ((CAMW%STGW)==0) ? STGW : (((CAMW%STGW)==1) ? (STGW+1) : (CAMW%STGW)); // last stage width 59 | 60 | // generate and instantiate transposed RAM structure 61 | wire [CAMD-1:0] matchStg [nSTG-1:0]; 62 | genvar gi; 63 | generate 64 | for (gi=0 ; gi10, use the entire M20K block, otherwise use internal M20K byte enables 66 | if ( (BYTEW>10) || (MEMD>1024) ) 67 | for (bi=0 ; bi \ ## 39 | ## ## 40 | ## - mux width & data width are positive integers ## 41 | ## - internal mux width is the width of the basic mux block used to construct ## 42 | ## the wide mux ## 43 | ## - register inputs/outputs is a binary (0/1) indicating if inputs/outputs ## 44 | ## should be registerd for pipelining ## 45 | ## - maximum combinatorial mux depth is acheived by pipelining ## 46 | ## - Top module name and file will be "mux_" ## 47 | ## EXAMPLES: ## 48 | ## ./mux 1024 32 4 1 1 1 cam ## 49 | ## - Will generate Verilog files for a 1K wide mux with 32bit data ## 50 | ## - Registered inputs and outputs; maximum 4 inputs width combinatorial mux ## 51 | ## - Top level name will be mux_cam and will be located in mux_cam.v ## 52 | ## The following files and directories will be created: ## 53 | ## - mux_.v: mux top module file ## 54 | #################################################################################### 55 | 56 | ################################## ARGUMENTS CHECK ################################# 57 | 58 | # require exactly 7 arguments 59 | if (${#argv} != 7) then 60 | printf '\x1b[%i;3%im' 1 1 61 | printf 'Error: Exactly 7 argument are required\n' 62 | printf '\x1b[0m' 63 | goto errorMessage 64 | endif 65 | 66 | # mux width 67 | # check argument correctness (positive integer number) 68 | if ( (`echo ${argv[1]} | egrep -c '^[0-9]+$'` != 1) || (${argv[1]} < 2) ) then 69 | printf '\x1b[%i;3%im' 1 1 70 | printf "Error (${argv[1]}): mux width must be possitive integer number\n" 71 | printf '\x1b[0m' 72 | goto errorMessage 73 | endif 74 | @ MW = ${argv[1]} 75 | 76 | # data width 77 | # check argument correctness (positive integer number) 78 | if ( (`echo ${argv[2]} | egrep -c '^[0-9]+$'` != 1) ) then 79 | printf '\x1b[%i;3%im' 1 1 80 | printf "Error (${argv[2]}): data width must be a possitive integer\n" 81 | printf '\x1b[0m' 82 | goto errorMessage 83 | endif 84 | @ DW = ${argv[2]} 85 | 86 | # internal mux width 87 | # check argument correctness (positive integer number) 88 | if ((`echo ${argv[3]} | egrep -c '^[0-9]+$'` != 1) || (${argv[3]} < 2) ) then 89 | printf '\x1b[%i;3%im' 1 1 90 | printf "Error (${argv[3]}): mux maximum combinatorial width should be larger than 1\n" 91 | printf '\x1b[0m' 92 | goto errorMessage 93 | endif 94 | @ IW = ${argv[3]} 95 | 96 | # register inputs? (binary) 97 | # check argument correctness (binary 0/1) 98 | if ( (${argv[4]} != "0") & (${argv[4]} != "1") )then 99 | printf '\x1b[%i;3%im' 1 1 100 | printf "Error (${argv[4]}): Register inputs? should be a binary 0/1\n" 101 | printf '\x1b[0m' 102 | goto errorMessage 103 | endif 104 | @ RI = ${argv[4]} 105 | 106 | # # register outputs? (binary) 107 | # check argument correctness (binary 0/1) 108 | if ( (${argv[5]} != "0") & (${argv[5]} != "1") )then 109 | printf '\x1b[%i;3%im' 1 1 110 | printf "Error (${argv[5]}): Register outputs? should be a binary 0/1\n" 111 | printf '\x1b[0m' 112 | goto errorMessage 113 | endif 114 | @ RO = ${argv[5]} 115 | 116 | # maximum combinatorial mux depth 117 | # check argument correctness (positive integer number) 118 | if ((`echo ${argv[6]} | egrep -c '^[0-9]+$'` != 1) || (${argv[6]} < 1) ) then 119 | printf '\x1b[%i;3%im' 1 1 120 | printf "Error (${argv[6]}): mux maximum combinatorial depth must be a possitive integer\n" 121 | printf '\x1b[0m' 122 | goto errorMessage 123 | endif 124 | @ CD = ${argv[6]} 125 | 126 | # top module suffex 127 | set MS = ${argv[7]} 128 | 129 | ################################## ARGUMENTS CHECK ################################# 130 | 131 | 132 | # reserved keywords 133 | set REG = "always @(posedge clk, posedge rst)\n if (rst) %s = %d'b0;\n else %s = %s;\n" 134 | 135 | # upper(log2(mux width)) 136 | @ i = 2 137 | @ L2MW = 1 138 | while ($i < $MW) 139 | @ i = $i * 2 140 | @ L2MW++ 141 | end 142 | 143 | # upper(log2(internal mux width)) 144 | @ i = 2 145 | @ L2IW = 1 146 | while ($i < $IW) 147 | @ i = $i * 2 148 | @ L2IW++ 149 | end 150 | 151 | # wide pipelined mux top module file 152 | 153 | printf "// mux_$MS.v: wide pipelined mux; automatically generated\n" >! mux_$MS.v 154 | printf "// input data is a packed ${i}x${DW} vector\n" >> mux_$MS.v 155 | printf "// Ameer Abedlhadi; April 2014 - University of British Columbia\n\n" >> mux_$MS.v 156 | printf "module mux_$MS(input clk, input rst, input [$MW*$DW-1:0] dat, input [$L2MW-1:0] sel, output [$DW-1:0] out);\n" >> mux_$MS.v 157 | 158 | if $RI then 159 | printf "\n// register mux inputs\n" >> mux_$MS.v 160 | printf "reg [$MW*$DW-1:0] w0;\n" >> mux_$MS.v 161 | printf "reg [$L2MW-1:0] s0i;\n" >> mux_$MS.v 162 | printf "$REG" w0 `expr $MW \* $DW` w0 dat >> mux_$MS.v 163 | printf "$REG" s0i $L2MW s0i sel >> mux_$MS.v 164 | 165 | else 166 | printf "wire [$MW*$DW-1:0] w0 = dat;\n" >> mux_$MS.v 167 | printf "wire [$L2MW-1:0] s0i = sel;\n" >> mux_$MS.v 168 | endif 169 | 170 | ## selector padding width 171 | @ spw = ($L2IW - ($L2MW % $L2IW)) % $L2IW 172 | 173 | ## selector width 174 | @ sw = $L2MW + $spw 175 | 176 | printf "\n// selector padding\n" >> mux_$MS.v 177 | set tmp = "s0i"; if $spw set tmp = "{$spw'b0,s0i}"; printf "wire [$sw-1:0] s0 = $tmp;\n" >> mux_$MS.v 178 | 179 | ## current width 180 | @ cw = $MW 181 | 182 | ## current stage number 183 | @ cs = 0 184 | 185 | while ($cw > 1) 186 | 187 | ## padding width 188 | @ pw = ($IW - ($cw % $IW)) % $IW 189 | 190 | ## add padding width to current stage width 191 | @ cw = $cw + $pw 192 | 193 | ## next stage width = number of muxes in current stage 194 | @ nw = $cw / $IW 195 | 196 | ## next stage number 197 | @ ns = $cs + 1 198 | 199 | printf "\n//////////////\n// stage #$cs //\n//////////////\n\n" >> mux_$MS.v 200 | set tmp = "w$cs"; if $pw set tmp = "{{($pw*$DW){1'b0}},w$cs}"; printf "wire [$cw*$DW-1:0] w${cs}p = $tmp; // padding input to stage $cs\n" >> mux_$MS.v 201 | printf "wire [$nw*$DW-1:0] w${ns}i; // output of stage $cs (unregistered)\n" >> mux_$MS.v 202 | 203 | ## number of muxes in current stage 204 | printf "\n// muxes for stage #$cs\n" >> mux_$MS.v 205 | @ nwl = `echo -n $nw|wc -c` 206 | foreach i (`awk "BEGIN { for (i=0; i<$nw; i++) print i; exit }"`) 207 | printf "mux${IW}x${DW}_${MS} mux${IW}x${DW}_${MS}_${cs}_%0${nwl}d (w${cs}p[$DW*$IW*%${nwl}d +: $DW*$IW],s${cs}[$L2IW-1:0],w${ns}i[%0${nwl}d*$DW +: $DW]);\n" $i $i $i >> mux_$MS.v 208 | end 209 | 210 | ## pipelining 211 | if ( !($ns % $CD) & ($nw > 1) ) then 212 | printf "\n// register stage $cs\n" >> mux_$MS.v 213 | printf "reg [$nw*$DW-1:0] w${ns};\n" >> mux_$MS.v 214 | printf "reg [$sw-$L2IW-1:0] s${ns};\n" >> mux_$MS.v 215 | printf "$REG" w$ns `expr $nw \* $DW` w$ns w${ns}i >> mux_$MS.v 216 | if ($nw > 1) printf "$REG" s$ns `expr $sw - $L2IW` s$ns "s${cs}[$sw-1:$L2IW]" >> mux_$MS.v 217 | else 218 | printf "wire [$nw*$DW-1:0] w$ns = w${ns}i; // data output of stage $cs\n" >> mux_$MS.v 219 | if ($nw > 1) printf "wire [$sw-$L2IW-1:0] s$ns = s${cs}[$sw-1:$L2IW]; // selector output of stage $cs\n" >> mux_$MS.v 220 | endif 221 | 222 | ## selector width passed for next stage 223 | @ sw = $sw - $L2IW 224 | 225 | ## stage width for next stage 226 | @ cw = $nw 227 | 228 | ## stage number for next stage 229 | @ cs = $ns 230 | 231 | end 232 | 233 | ## register output 234 | if $RO then 235 | printf "\n// register output\n" >> mux_$MS.v 236 | printf "reg [$DW-1:0] outR;\n" >> mux_$MS.v 237 | printf "$REG" outR $DW outR w$cs >> mux_$MS.v 238 | printf "assign out = outR; // assign output to last stage / registered\n" >> mux_$MS.v 239 | else 240 | printf "assign out = w$cs; // assign output to last stage\n" >> mux_$MS.v 241 | endif 242 | 243 | printf "\nendmodule\n" >> mux_$MS.v 244 | 245 | ## basic ${IW} x ${DW} mux 246 | printf "\n//////////////////////\n// basic ${IW} x ${DW} mux //\n//////////////////////\n" >> mux_$MS.v 247 | printf "module mux${IW}x${DW}_${MS}(input [$IW*$DW-1:0] dat, input [$L2IW-1:0] sel, output [$DW-1:0] out);\n" >> mux_$MS.v 248 | @ DWL = `echo -n $DW|wc -c` 249 | foreach i (`awk "BEGIN { for (i=0; i<$DW; i++) print i; exit }"`) 250 | printf "mux${IW}x1_${MS} mux${IW}x1_${MS}_%0${DWL}d ({dat[%${DWL}d+3*$DW],dat[%${DWL}d+2*$DW],dat[%${DWL}d+$DW],dat[%${DWL}d]},sel,out[%${DWL}d]); // mux slice\n" $i $i $i $i $i $i >> mux_$MS.v 251 | end 252 | printf "endmodule\n" >> mux_$MS.v 253 | 254 | ## basic ${IW} x 1 mux 255 | printf "\n/////////////////////\n// basic ${IW} x 1 mux //\n/////////////////////\n" >> mux_$MS.v 256 | printf "module mux${IW}x1_${MS}(input [$IW-1:0] dat, input [$L2IW-1:0] sel, output out);\n" >> mux_$MS.v 257 | printf "assign out = dat[sel];\n" >> mux_$MS.v 258 | printf "endmodule\n" >> mux_$MS.v 259 | 260 | goto scriptEnd 261 | 262 | ################################## ERROR MESSAGE #################################### 263 | 264 | errorMessage: 265 | printf '\x1b[%i;3%im' 1 1 266 | cat << EOH 267 | USAGE: 268 | ./mux \ 269 | 270 | - mux width & data width are positive integers 271 | - internal mux width is the width of the basic mux block used to construct 272 | the wide mux 273 | - register inputs/outputs is a binary (0/1) indicating if inputs/outputs 274 | should be registerd for pipelining 275 | - maximum combinatorial mux depth is acheived by pipelining 276 | - Top module name and file will be "mux_" 277 | EXAMPLES: 278 | ./mux 1024 32 4 1 1 1 cam 279 | - Will generate Verilog files for a 1K wide mux with 32bit data 280 | - Registered inputs and outputs; maximum 4 inputs width combinatorial mux 281 | - Top level name will be mux_cam and will be located in mux_cam.v 282 | The following files and directories will be created: 283 | - mux_.v: mux top module file 284 | EOH 285 | printf '\x1b[0m' 286 | scriptEnd: 287 | 288 | -------------------------------------------------------------------------------- /mwram_gen.v: -------------------------------------------------------------------------------- 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 | // mwram_gen.v: Generic mixed width RAM; not synthesizable with Altera's devices. // 29 | // May not be synthesizable with other vendors; // 30 | // Check your vendor's recommended HDL coding style. // 31 | // // 32 | // Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 33 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 34 | //////////////////////////////////////////////////////////////////////////////////// 35 | 36 | `include "utils.vh" 37 | 38 | module mwram_gen 39 | #( parameter WR_DW = 1 , // write data width 40 | parameter RD_DW = 32 , // read data width (a multiply of WR_DW) 41 | parameter RD_D = 512, // read depth 42 | parameter IZERO = 1 ) // initialize to zeros 43 | ( input clk , // clock 44 | input rst , // global registers reset 45 | input wEnb , // write enable 46 | input [`log2(RD_D*RD_DW/WR_DW)-1:0] wAddr , // write address 47 | input [WR_DW -1:0] wData , // write data 48 | input [`log2(RD_D) -1:0] rAddr , // read address 49 | output reg [RD_DW -1:0] rData ); // read data 50 | 51 | localparam WR_D = RD_D*RD_DW/WR_DW ; // write depth 52 | localparam WR_AW = `log2(WR_D) ; // write address width 53 | localparam RD_AW = `log2(RD_D) ; // read address width 54 | localparam DSELW = `log2(RD_DW/WR_DW); // data selector width 55 | 56 | reg [RD_DW-1:0] mem [0:RD_D-1]; // memory array 57 | integer iA; 58 | 59 | initial 60 | if (IZERO) 61 | for (iA=0; iA \ ## 39 | ## ## 40 | ## - Encoder width is a positive integer ## 41 | ## - Register inputs/outputs is a binary (0/1) indicating if inputs/outputs ## 42 | ## should be registerd for pipelining ## 43 | ## - combinatorial maximum depth is acheived by pipelining ## 44 | ## - Mux type should be "CASE", "IFELSE" or "AS5EXT" ## 45 | ## - "CASE" : standard binary 4->1 mux using case statement ## 46 | ## - "IFELSE": using if/else statement ## 47 | ## - "AS5EXT": Altera's StratixV extended ALM (7LUT) ## 48 | ## - Top module name and file will be "pe_" ## 49 | ## EXAMPLES: ## 50 | ## ./pe 1024 1 1 2 CASE cam ## 51 | ## - Will generate Verilog files for a 1K wide priority encoder ## 52 | ## - Registered inputs and outputs; maximum two stages deep logic ## 53 | ## - Muxes are implemented using case statement ## 54 | ## - Top level name will be pe1024_cam and will be located in pe1024_cam.v ## 55 | ## ## 56 | ## The following files and directories will be created: ## 57 | ## - pe_.v: priority encoder top module file ## 58 | ## - pe.v : i = 4, 16, 64, 256, 1024... recursive priority encoder ## 59 | #################################################################################### 60 | 61 | ################################## ARGUMENTS CHECK ################################# 62 | 63 | # require exactly 6 arguments 64 | if (${#argv} != 6) then 65 | printf '\x1b[%i;3%im' 1 1 66 | printf 'Error: Exactly 6 argument are required\n' 67 | printf '\x1b[0m' 68 | goto errorMessage 69 | endif 70 | 71 | # priority encoder width 72 | # check argument correctness (positive integer number) 73 | if ( (`echo ${argv[1]} | egrep -c '^[0-9]+$'` != 1) || (${argv[1]} < 2) ) then 74 | printf '\x1b[%i;3%im' 1 1 75 | printf "Error (${argv[1]}): Priority encoder width must be possitive integer number\n" 76 | printf '\x1b[0m' 77 | goto errorMessage 78 | endif 79 | @ PEW = ${argv[1]} 80 | 81 | # register inputs? (binary) 82 | # check argument correctness (binary 0/1) 83 | if ( (${argv[2]} != "0") & (${argv[2]} != "1") )then 84 | printf '\x1b[%i;3%im' 1 1 85 | printf "Error (${argv[2]}): Register inputs? should be a binary 0/1\n" 86 | printf '\x1b[0m' 87 | goto errorMessage 88 | endif 89 | @ RI = ${argv[2]} 90 | 91 | # # register outputs? (binary) 92 | # check argument correctness (binary 0/1) 93 | if ( (${argv[3]} != "0") & (${argv[3]} != "1") )then 94 | printf '\x1b[%i;3%im' 1 1 95 | printf "Error (${argv[3]}): Register outputs? should be a binary 0/1\n" 96 | printf '\x1b[0m' 97 | goto errorMessage 98 | endif 99 | @ RO = ${argv[3]} 100 | 101 | # combinatorial maximum depth 102 | # check argument correctness (positive integer number) 103 | if ((`echo ${argv[4]} | egrep -c '^[0-9]+$'` != 1) || (${argv[4]} < 1) ) then 104 | printf '\x1b[%i;3%im' 1 1 105 | printf "Error (${argv[4]}): Combinatorial maximum depth must be possitive integer number\n" 106 | printf '\x1b[0m' 107 | goto errorMessage 108 | endif 109 | @ CMD = ${argv[4]} 110 | 111 | # mux implementation 112 | # check argument correctness ("CASE", "IFELSE", "AS5EXT") 113 | if ( (${argv[5]} != "CASE") && (${argv[5]} != "IFELSE") && (${argv[5]} != "AS5EXT") ) then 114 | printf '\x1b[%i;3%im' 1 1 115 | printf 'Error (%s): Mux type should be "CASE", "IFELSE", or "AS5EXT" \n' ${argv[5]} 116 | printf '\x1b[0m' 117 | goto errorMessage 118 | endif 119 | set MUX = ${argv[5]} 120 | 121 | # top module suffex 122 | set TMS = ${argv[6]} 123 | 124 | ################################## ARGUMENTS CHECK ################################# 125 | 126 | # upper(log2(width)) 127 | @ j = 2 128 | @ l2w = 1 129 | while ($j < $PEW) 130 | @ j = $j * 2 131 | @ l2w++ 132 | end 133 | 134 | # reserved keywords 135 | set ELSE = "else" 136 | 137 | @ i = 1 138 | @ l2i = 0 139 | @ l4i = 0 140 | while ($i < $PEW) 141 | @ ip = $i 142 | @ i = $i * 4 143 | @ l2i = $l2i + 2 144 | @ l4i = $l4i + 1 145 | # wide recursive priority encoder based on narrower priority encoder 146 | printf "" >! pe${i}.v 147 | 148 | ###################################### VERILOG ###################################### 149 | cat >> pe${i}.v << EOV 150 | // pe${i}: recursive priority encoder based; Automatically generated 151 | // Ameer Abedlhadi ; April 2014 - The University of British Columbia 152 | // i: $i, l2i: $l2i, l4i: $l4i 153 | module pe${i}(input clk, input rst, input [$i-1:0] oht, output [$l2i-1:0] bin, output vld); 154 | EOV 155 | ##################################################################################### 156 | 157 | if ($i == 4) then 158 | 159 | ###################################### VERILOG ###################################### 160 | cat >> pe${i}.v << EOV 161 | assign {bin,vld} = {!(oht[0]||oht[1]),!oht[0]&&(oht[1]||!oht[2]),|oht}; 162 | EOV 163 | ##################################################################################### 164 | 165 | else 166 | 167 | ###################################### VERILOG ###################################### 168 | cat >> pe${i}.v << EOV 169 | // recursive calls for four narrower (fourth the inout width) priority encoders 170 | wire [$l2i-3:0] binI[3:0]; 171 | wire [ 3:0] vldI ; 172 | pe${ip} pe${ip}_in0(clk, rst, oht[ $i/4-1:0 ],binI[0],vldI[0]); 173 | pe${ip} pe${ip}_in1(clk, rst, oht[ $i/2-1: $i/4 ],binI[1],vldI[1]); 174 | pe${ip} pe${ip}_in2(clk, rst, oht[3*$i/4-1: $i/2 ],binI[2],vldI[2]); 175 | pe${ip} pe${ip}_in3(clk, rst, oht[ $i -1:3*$i/4 ],binI[3],vldI[3]); 176 | // register input priority encoders outputs if pipelining is required; otherwise assign only 177 | wire [$l2i-3:0] binII[3:0]; 178 | wire [ 3:0] vldII ; 179 | EOV 180 | ##################################################################################### 181 | 182 | if ( ( ( $l4i - 1 ) % $CMD ) == 0 ) then 183 | 184 | ###################################### VERILOG ###################################### 185 | cat >> pe${i}.v << EOV 186 | reg [$l2i-3:0] binIR[3:0]; 187 | reg [ 3:0] vldIR ; 188 | always @(posedge clk, posedge rst) 189 | if (rst) {binIR[3],binIR[2],binIR[1],binIR[0],vldIR} <= {(4*($l2i-1)){1'b0}}; 190 | $ELSE {binIR[3],binIR[2],binIR[1],binIR[0],vldIR} <= {binI[3],binI[2],binI[1],binI[0],vldI}; 191 | assign {binII[3],binII[2],binII[1],binII[0],vldII} = {binIR[3],binIR[2],binIR[1],binIR[0],vldIR}; 192 | EOV 193 | ##################################################################################### 194 | 195 | else 196 | 197 | ###################################### VERILOG ###################################### 198 | cat >> pe${i}.v << EOV 199 | assign {binII[3],binII[2],binII[1],binII[0],vldII} = {binI[3],binI[2],binI[1],binI[0],vldI}; 200 | EOV 201 | ##################################################################################### 202 | 203 | endif 204 | 205 | ###################################### VERILOG ###################################### 206 | cat >> pe${i}.v << EOV 207 | // output pe4 to generate indices from valid bits 208 | pe4 pe4_out0(clk,rst,vldII,bin[$l2i-1:$l2i-2],vld); 209 | EOV 210 | ##################################################################################### 211 | 212 | if ($MUX == "AS5EXT") then 213 | 214 | ###################################### VERILOG ###################################### 215 | cat >> pe${i}.v << EOV 216 | // generate stratixv_lcell_comb for extended 7LUT to implement the mux 217 | wire [$l2i-3:0] binO; 218 | genvar gi; 219 | generate 220 | for (gi=0 ; gi<($l2i-2) ; gi=gi+1) begin: LUTgi 221 | stratixv_lcell_comb #( 222 | .lut_mask (64'hF0F0FF00F0F0CACA), 223 | .shared_arith("off" ), 224 | .extended_lut("on" ), 225 | .dont_touch ("off" ) 226 | ) 227 | stratixv_lcell_ext_mux_inst ( 228 | .dataa (binII[3][gi] ), 229 | .datab (binII[2][gi] ), 230 | .datac (vldII[2] ), 231 | .datad (binII[1][gi] ), 232 | .datae (vldII[0] ), 233 | .dataf (vldII[1] ), 234 | .datag (binII[0][gi] ), 235 | .cin (1'b0 ), 236 | .sharein (1'b0 ), 237 | .combout (binO[gi] ), 238 | .sumout ( ), 239 | .cout ( ), 240 | .shareout ( ) 241 | ); 242 | end 243 | endgenerate 244 | EOV 245 | ##################################################################################### 246 | 247 | else if ($MUX == "IFELSE") then 248 | 249 | ###################################### VERILOG ###################################### 250 | cat >> pe${i}.v << EOV 251 | // implement the mux with a 7-inputs ALM in extended mode for each output 252 | reg [$l2i-3:0] binO; 253 | always @(*) 254 | if (vldII[0]) binO = binII[0]; 255 | $ELSE if (vldII[1]) binO = binII[1]; 256 | $ELSE if (vldII[2]) binO = binII[2]; 257 | $ELSE binO = binII[3]; 258 | EOV 259 | ##################################################################################### 260 | 261 | else 262 | 263 | ###################################### VERILOG ###################################### 264 | cat >> pe${i}.v << EOV 265 | // a 4->1 mux to steer indices from the narrower pe's 266 | reg [$l2i-3:0] binO; 267 | always @(*) 268 | case (bin[$l2i-1:$l2i-2]) 269 | 2'b00: binO = binII[0]; 270 | 2'b01: binO = binII[1]; 271 | 2'b10: binO = binII[2]; 272 | 2'b11: binO = binII[3]; 273 | endcase 274 | EOV 275 | ##################################################################################### 276 | 277 | endif 278 | 279 | ###################################### VERILOG ###################################### 280 | cat >> pe${i}.v << EOV 281 | assign bin[$l2i-3:0] = binO; 282 | EOV 283 | ##################################################################################### 284 | 285 | endif 286 | 287 | ###################################### VERILOG ###################################### 288 | cat >> pe${i}.v << EOV 289 | endmodule 290 | EOV 291 | ##################################################################################### 292 | 293 | end 294 | 295 | # priority encoder top module file 296 | 297 | printf "" >! pe_$TMS.v 298 | 299 | ###################################### VERILOG ###################################### 300 | cat >> pe_$TMS.v << EOV 301 | // pe_$TMS.v: priority encoder top module file 302 | // Automatically generated for priority encoder design 303 | // Ameer Abedlhadi; April 2014 - University of British Columbia 304 | 305 | module pe_$TMS(input clk, input rst, input [$PEW-1:0] oht, output [$l2w-1:0] bin, output vld); 306 | EOV 307 | ##################################################################################### 308 | 309 | if ($RI == "1") then 310 | 311 | ###################################### VERILOG ###################################### 312 | cat >> pe_$TMS.v << EOV 313 | // register input (oht) 314 | reg [$PEW-1:0] ohtR; 315 | always @(posedge clk, posedge rst) 316 | if (rst) ohtR <= {$PEW{1'b0}}; 317 | $ELSE ohtR <= oht; 318 | EOV 319 | ##################################################################################### 320 | 321 | else 322 | 323 | ###################################### VERILOG ###################################### 324 | cat >> pe_$TMS.v << EOV 325 | wire [$PEW-1:0] ohtR = oht; 326 | EOV 327 | ##################################################################################### 328 | 329 | endif 330 | 331 | ###################################### VERILOG ###################################### 332 | cat >> pe_$TMS.v << EOV 333 | wire [$l2w-1:0] binII; 334 | wire vldI ; 335 | // instantiate peiority encoder 336 | EOV 337 | ##################################################################################### 338 | 339 | if ($i > $PEW) then 340 | 341 | ###################################### VERILOG ###################################### 342 | cat >> pe_$TMS.v << EOV 343 | wire [$i-1:0] ohtI = {{($i-$PEW){1'b0}},ohtR}; 344 | wire [$l2i-1:0] binI ; 345 | pe${i} pe${i}_0(clk,rst,ohtI,binI,vldI); 346 | assign binII = binI[$l2w-1:0]; 347 | EOV 348 | ##################################################################################### 349 | 350 | else 351 | 352 | ###################################### VERILOG ###################################### 353 | cat >> pe_$TMS.v << EOV 354 | pe${i} pe${i}_0(clk,rst,ohtR,binII,vldI); 355 | EOV 356 | ##################################################################################### 357 | 358 | endif 359 | 360 | if ($RO == "1") then 361 | 362 | ###################################### VERILOG ###################################### 363 | cat >> pe_$TMS.v << EOV 364 | // register outputs (bin, vld) 365 | reg [$l2w-1:0] binIIR; 366 | reg vldIR ; 367 | always @(posedge clk, posedge rst) 368 | if (rst) {binIIR,vldIR} <= {($l2w+1){1'b0}}; 369 | $ELSE {binIIR,vldIR} <= {binII,vldI}; 370 | assign {bin,vld} = {binIIR,vldIR}; 371 | EOV 372 | ##################################################################################### 373 | 374 | else 375 | 376 | ###################################### VERILOG ###################################### 377 | cat >> pe_$TMS.v << EOV 378 | assign {bin,vld} = {binII ,vldI }; 379 | EOV 380 | ##################################################################################### 381 | 382 | endif 383 | 384 | ###################################### VERILOG ###################################### 385 | cat >> pe_$TMS.v << EOV 386 | endmodule 387 | EOV 388 | ##################################################################################### 389 | 390 | goto scriptEnd 391 | 392 | ################################## ERROR MESSAGE #################################### 393 | 394 | errorMessage: 395 | printf '\x1b[%i;3%im' 1 1 396 | cat << EOH 397 | USAGE: 398 | ./pe \ 399 | 400 | - Encoder width is a positive integer 401 | - Register inputs/outputs is a binary (0/1) indicating if inputs/outputs 402 | should be registerd for pipelining 403 | - combinatorial maximum depth is acheived by pipelining 404 | - Mux type should be "CASE", "IFELSE" or "AS5EXT" 405 | - "CASE" : standard binary 4->1 mux using case statement 406 | - "IFELSE": using if/else statement 407 | - "AS5EXT": Altera's StratixV extended ALM (7LUT) 408 | - Top module name and file will be "pe_" 409 | EXAMPLES: 410 | ./pe 1024 1 1 2 CASE cam 411 | - Will generate Verilog files for a 1K wide priority encoder 412 | - Registered inputs and outputs; maximum two stages deep logic 413 | - Muxes are implemented using case statement 414 | - Top level name will be pe1024_cam and will be located in pe1024_cam.v 415 | 416 | The following files and directories will be created: 417 | - pe_.v: priority encoder top module file 418 | - pe.v : i = 4, 16, 64, 256, 1024... recursive priority encoder 419 | EOH 420 | printf '\x1b[0m' 421 | scriptEnd: 422 | 423 | -------------------------------------------------------------------------------- /reduction: -------------------------------------------------------------------------------- 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 | ## reduction: Wide pipelined reduction function generator (c-shell) ## 31 | ## ## 32 | ## Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) ## 33 | ## SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 ## 34 | #################################################################################### 35 | 36 | #################################################################################### 37 | ## USAGE: ## 38 | ## ./reduction \ ## 39 | ## ## 40 | ## - data width is positive integers ## 41 | ## - internal logic block width is the width of the basic logic block used to ## 42 | ## construct the wide reduction ## 43 | ## - register inputs/outputs is a binary (0/1) indicating if inputs/outputs ## 44 | ## should be registerd for pipelining ## 45 | ## - maximum combinatorial mux depth is acheived by pipelining ## 46 | ## - Top module name and file will be "reduction_" ## 47 | ## EXAMPLES: ## 48 | ## ./reduction 1024 6 1 1 1 OR or ## 49 | ## - Will generate Verilog files for a 1K wide reduction OR ## 50 | ## - Registered inputs and outputs; maximum 6 inputs width combinatorial OR ## 51 | ## - Top level will be reduction_or and will be located in reduction_or.v ## 52 | ## The following files and directories will be created: ## 53 | ## - reduction_.v: reduction function top module file ## 54 | #################################################################################### 55 | 56 | ################################## ARGUMENTS CHECK ################################# 57 | 58 | # require exactly 7 arguments 59 | if (${#argv} != 7) then 60 | printf '\x1b[%i;3%im' 1 1 61 | printf 'Error: Exactly 7 argument are required\n' 62 | printf '\x1b[0m' 63 | goto errorMessage 64 | endif 65 | 66 | # data width 67 | # check argument correctness (positive integer number) 68 | if ( (`echo ${argv[1]} | egrep -c '^[0-9]+$'` != 1) ) then 69 | printf '\x1b[%i;3%im' 1 1 70 | printf "Error (${argv[1]}): input data width must be a possitive integer\n" 71 | printf '\x1b[0m' 72 | goto errorMessage 73 | endif 74 | @ DW = ${argv[1]} 75 | 76 | # internal logic block width 77 | # check argument correctness (positive integer number) 78 | if ((`echo ${argv[2]} | egrep -c '^[0-9]+$'` != 1) || (${argv[2]} < 2) ) then 79 | printf '\x1b[%i;3%im' 1 1 80 | printf "Error (${argv[2]}): internal logic block width must be larger than 1\n" 81 | printf '\x1b[0m' 82 | goto errorMessage 83 | endif 84 | @ IW = ${argv[2]} 85 | 86 | # register inputs? (binary) 87 | # check argument correctness (binary 0/1) 88 | if ( (${argv[3]} != "0") & (${argv[3]} != "1") )then 89 | printf '\x1b[%i;3%im' 1 1 90 | printf "Error (${argv[3]}): Register inputs? should be a binary 0/1\n" 91 | printf '\x1b[0m' 92 | goto errorMessage 93 | endif 94 | @ RI = ${argv[3]} 95 | 96 | # # register outputs? (binary) 97 | # check argument correctness (binary 0/1) 98 | if ( (${argv[4]} != "0") & (${argv[4]} != "1") )then 99 | printf '\x1b[%i;3%im' 1 1 100 | printf "Error (${argv[4]}): Register outputs? should be a binary 0/1\n" 101 | printf '\x1b[0m' 102 | goto errorMessage 103 | endif 104 | @ RO = ${argv[4]} 105 | 106 | # maximum combinatorial depth 107 | # check argument correctness (positive integer number) 108 | if ((`echo ${argv[5]} | egrep -c '^[0-9]+$'` != 1) || (${argv[5]} < 1) ) then 109 | printf '\x1b[%i;3%im' 1 1 110 | printf "Error (${argv[5]}): reduction function maximum combinatorial depth must be a possitive integer\n" 111 | printf '\x1b[0m' 112 | goto errorMessage 113 | endif 114 | @ CD = ${argv[5]} 115 | 116 | # reduction functiob 117 | # check argument correctness ("AND", "OR", "XOR") 118 | 119 | switch (${argv[6]}) 120 | case AND: 121 | set RF = '&' 122 | breaksw 123 | case OR: 124 | set RF = '|' 125 | breaksw 126 | case XOR: 127 | set RF = '^' 128 | breaksw 129 | default: 130 | printf '\x1b[%i;3%im' 1 1 131 | printf 'Error (%s): reduction function should be "AND", "OR", or "XOR" \n' ${argv[6]} 132 | printf '\x1b[0m' 133 | goto errorMessage 134 | endsw 135 | 136 | # top module suffex 137 | set MS = ${argv[7]} 138 | 139 | ################################## ARGUMENTS CHECK ################################# 140 | 141 | 142 | # reserved keywords 143 | set REG = "always @(posedge clk, posedge rst)\n if (rst) %s = %d'b0;\n else %s = %s;\n" 144 | 145 | # upper(log2(data width)) 146 | @ i = 2 147 | @ L2DW = 1 148 | while ($i < $DW) 149 | @ i = $i * 2 150 | @ L2DW++ 151 | end 152 | 153 | # upper(log2(internal logic block width)) 154 | @ i = 2 155 | @ L2IW = 1 156 | while ($i < $IW) 157 | @ i = $i * 2 158 | @ L2IW++ 159 | end 160 | 161 | # wide pipelined reduction function top module file 162 | 163 | printf "// reduction_$MS.v: wide pipelined reduction function; automatically generated\n" >! reduction_$MS.v 164 | printf "// input data is a ${DW} bit vector\n" >> reduction_$MS.v 165 | printf "// Ameer Abedlhadi; April 2014 - University of British Columbia\n\n" >> reduction_$MS.v 166 | printf "module reduction_$MS(input clk, input rst, input [$DW-1:0] dat, output out);\n" >> reduction_$MS.v 167 | 168 | if $RI then 169 | printf "\n// register inputs\n" >> reduction_$MS.v 170 | printf "reg [$DW-1:0] w0;\n" >> reduction_$MS.v 171 | printf "$REG" w0 $DW w0 dat >> reduction_$MS.v 172 | else 173 | printf "wire [$DW-1:0] w0 = dat;\n" >> reduction_$MS.v 174 | endif 175 | 176 | ## current width 177 | @ cw = $DW 178 | 179 | ## current stage number 180 | @ cs = 0 181 | 182 | while ($cw > 1) 183 | 184 | ## padding width 185 | @ pw = ($IW - ($cw % $IW)) % $IW 186 | 187 | ## add padding width to current stage width 188 | @ cw = $cw + $pw 189 | 190 | ## next stage width = number of blocks in current stage 191 | @ nw = $cw / $IW 192 | 193 | ## next stage number 194 | @ ns = $cs + 1 195 | 196 | printf "\n//////////////\n// stage #$cs //\n//////////////\n\n" >> reduction_$MS.v 197 | set tmp = "w$cs"; if $pw set tmp = "{$pw'b0,w$cs}"; printf "wire [$cw-1:0] w${cs}p = $tmp; // padding input to stage $cs\n" >> reduction_$MS.v 198 | printf "wire [$nw-1:0] w${ns}i; // output of stage $cs (unregistered)\n" >> reduction_$MS.v 199 | ############# 200 | ## number of muxes in current stage 201 | printf "\n// logic blocks for stage #$cs\n" >> reduction_$MS.v 202 | @ nwl = `echo -n $nw|wc -c` 203 | foreach i (`awk "BEGIN { for (i=0; i<$nw; i++) print i; exit }"`) 204 | printf "assign w${ns}i[%0${nwl}d] = $RF w${cs}p[$IW*%${nwl}d +: $IW];\n" $i $i >> reduction_$MS.v 205 | end 206 | 207 | ## pipelining 208 | if ( !($ns % $CD) & ($nw > 1) ) then 209 | printf "\n// register stage $cs\n" >> reduction_$MS.v 210 | printf "reg [$nw-1:0] w${ns};\n" >> reduction_$MS.v 211 | printf "$REG" w$ns $nw w$ns w${ns}i >> reduction_$MS.v 212 | else 213 | printf "wire [$nw-1:0] w$ns = w${ns}i; // data output of stage $cs\n" >> reduction_$MS.v 214 | endif 215 | 216 | ## stage width for next stage 217 | @ cw = $nw 218 | 219 | ## stage number for next stage 220 | @ cs = $ns 221 | 222 | end 223 | 224 | ## register output 225 | if $RO then 226 | printf "\n// register output\n" >> reduction_$MS.v 227 | printf "reg outR;\n" >> reduction_$MS.v 228 | printf "$REG" outR 1 outR w$cs >> reduction_$MS.v 229 | printf "assign out = outR; // assign output to last stage / registered\n" >> reduction_$MS.v 230 | else 231 | printf "assign out = w$cs; // assign output to last stage\n" >> reduction_$MS.v 232 | endif 233 | 234 | printf "\nendmodule\n" >> reduction_$MS.v 235 | 236 | goto scriptEnd 237 | 238 | ################################## ERROR MESSAGE #################################### 239 | 240 | errorMessage: 241 | printf '\x1b[%i;3%im' 1 1 242 | cat << EOH 243 | USAGE: 244 | ./reduction \ 245 | 246 | - data width is positive integers 247 | - internal logic block width is the width of the basic logic block used to 248 | construct the wide reduction 249 | - register inputs/outputs is a binary (0/1) indicating if inputs/outputs 250 | should be registerd for pipelining 251 | - maximum combinatorial mux depth is acheived by pipelining 252 | - Top module name and file will be "reduction_" 253 | EXAMPLES: 254 | ./reduction 1024 6 1 1 1 OR or 255 | - Will generate Verilog files for a 1K wide reduction OR 256 | - Registered inputs and outputs; maximum 6 inputs width combinatorial OR 257 | - Top level will be reduction_or and will be located in reduction_or.v 258 | The following files and directories will be created: 259 | - reduction_.v: reduction function top module file 260 | EOH 261 | printf '\x1b[0m' 262 | scriptEnd: 263 | 264 | -------------------------------------------------------------------------------- /sbram_m20k.v: -------------------------------------------------------------------------------- 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 | // sbram_m20k.v: Single-bit width RAM using Altera's M20K // 29 | // // 30 | // Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `include "utils.vh" 35 | 36 | module sbram_m20k 37 | #( parameter DEPTH = 16384, // read depth > 16K 38 | parameter IZERO = 1 ) // initialize to zeros 39 | ( input clk , // clock 40 | input rst , // global registers reset 41 | input wEnb , // write enable 42 | input [`log2(DEPTH)-1:0] wAddr , // write address 43 | input wData , // write data 44 | input [`log2(DEPTH)-1:0] rAddr , // read address 45 | output rData ); // read data 46 | 47 | localparam ADDRW = `log2(DEPTH); // 48 | localparam nM20K = DEPTH/16384; 49 | 50 | wire [nM20K-1:0] rDataAll; 51 | 52 | reg [nM20K-1:0] M20KSel; 53 | // binary to one-hot 54 | always @(*) begin 55 | M20KSel = 0 ; 56 | M20KSel[wAddr[ADDRW-1:14]] = wEnb; 57 | end 58 | 59 | 60 | // generate and instantiate mixed-width BRAMs 61 | genvar gi; 62 | generate 63 | for (gi=0 ; gi <#Cycles> ## 39 | ## ## 40 | ## - Use a comma delimited list; no space; can be surrounded by brackets ()[]{}<> ## 41 | ## - CAM depth, pattern width, segment width and cycles are positive integers ## 42 | ## ## 43 | ## EXAMPLES: ## 44 | ## ./sim 8192 9 8 1000000 ## 45 | ## Simulate 1M cycles of a 8K lines CAM, 9 bits pattern width, 8 bits segments ## 46 | ## ./sim 2048,4096 8,9,10 8,16 1000000 ## 47 | ## Simulate 1M cycles of CAMs with 2k or 4k lines, 8, 9, or 10 bits pattern, ## 48 | ## 8 or 16 bits segment. Total of 12 CAM 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 Altera's Modelsim for simulation; change to your own flow if necessary 56 | source /CMC/scripts/altera.13.1.csh 57 | source /CMC/tools/licenses/altera.csh 58 | setenv PATH ${QUARTUS_HOME}/../nios2eds/bin/:${QUARTUS_HOME}/../modelsim_ase/bin:${PATH} 59 | 60 | # require exactly 4 arguments 61 | if (${#argv} != 4) then 62 | printf '\x1b[%i;3%im' 1 1 63 | printf 'Error: Exactly 4 are required\n' 64 | printf '\x1b[0m' 65 | goto errorMessage 66 | endif 67 | 68 | # convert each argument list into a c-shell list (remove commas and etc.) 69 | set CAMDLST = (`echo ${argv[1]} | tr ",()[]{}<>" " "`) 70 | set PATWLST = (`echo ${argv[2]} | tr ",()[]{}<>" " "`) 71 | set SEGWLST = (`echo ${argv[3]} | tr ",()[]{}<>" " "`) 72 | set SCYCNUM = ${argv[4]} 73 | 74 | # check arguments correctness (positive integer numbers) 75 | foreach ARGVAL ($CAMDLST $PATWLST $SEGWLST $SCYCNUM) 76 | set ARGVALIsNumber=`echo $ARGVAL | egrep -c '^[0-9]+$'` 77 | if ($ARGVALIsNumber != 1) then 78 | printf '\x1b[%i;3%im' 1 1 79 | printf "Error (${ARGVAL}): CAM depth, pattern width, segment width and number of cycles arguments should be possitive integer numbers\n" 80 | printf '\x1b[0m' 81 | goto errorMessage 82 | endif 83 | end 84 | 85 | # total different fifo designs 86 | @ FlowOprNum = ((${#CAMDLST})*(${#PATWLST})*(${#SEGWLST})) 87 | @ FlowOprCnt = 0 88 | 89 | printf '\x1b[%i;3%im' 7 4 90 | printf "= Simulate in batch with the following parameters:\n" 91 | printf "= CAM Depth : $CAMDLST\n" 92 | printf "= Pattern width : $PATWLST\n" 93 | printf "= Segment width (STR): $SEGWLST\n" 94 | printf "= Simulation Cycles : $SCYCNUM\n" 95 | printf '\x1b[0m' 96 | 97 | # operate on all different RAM parameters 98 | foreach CURCAMD ($CAMDLST) 99 | foreach CURPATW ($PATWLST) 100 | foreach CURSEGW ($SEGWLST) 101 | @ FlowOprCnt++ 102 | 103 | printf '\x1b[%i;3%im' 7 2 104 | printf "\n== Starting Simulation (${FlowOprCnt}/${FlowOprNum}): [CAM depth:${CURCAMD}; Pattern width:${CURPATW}; Segment width:${CURSEGW}; Simulation cycles:${SCYCNUM}]\n" 105 | printf '\x1b[0m' 106 | 107 | # remove work directory to recompile verilog 108 | if (-d work) \rm -rf work 109 | # recreate work directory 110 | vlib work 111 | 112 | # Generate priority encoders 113 | \rm pe*.v 114 | ./pe $CURCAMD 0 0 999 CASE camd 115 | ./pe `expr $CURCAMD / $CURSEGW` 0 0 999 CASE nseg 116 | ./pe $CURSEGW 0 0 999 CASE segw 117 | 118 | # Generate reduction OR 119 | \rm reduction_or.v 120 | ./reduction $CURSEGW 6 0 0 999 OR or 121 | 122 | # Generate mux 123 | \rm mux_data2rmv.v 124 | ./mux $CURSEGW $CURPATW 4 0 0 999 data2rmv 125 | 126 | # run current simulation 127 | vlog -work work +define+CAMD=$CURCAMD+CAMW=$CURPATW+SEGW=$CURSEGW+CYCC=$SCYCNUM utils.vh pe*.v mux_*.v reduction_*.v spram.v mwram_gen.v mwram_m20k.v tdpram.v dpram_be.v trcam.v bcam_bhv.v bcam_reg.v bcam_trs.v bcam_trc.v bcam_str.v bcam_tb.v bcam.v 128 | vsim -c -L altera_mf_ver -L lpm_ver -L altera_ver -L stratixv_ver -do "run -all" bcam_tb 129 | 130 | printf '\x1b[%i;3%im' 7 2 131 | printf "== Simulation (${FlowOprCnt}/${FlowOprNum}) Completed: [CAM depth:${CURCAMD}; Pattern width:${CURPATW}; Segment width:${CURSEGW}; Simulation cycles:${SCYCNUM}]\n" 132 | printf '\x1b[0m' 133 | 134 | end 135 | end 136 | end 137 | 138 | # clean unrequired files / after run 139 | foreach fileName (*.mif *.hex *.ver *.wlf *.vstf *.log transcript work) 140 | \rm -rf $fileName 141 | end 142 | 143 | 144 | goto scriptEnd 145 | 146 | # error message 147 | errorMessage: 148 | printf '\x1b[%i;3%im' 1 1 149 | cat << EOH 150 | USAGE: 151 | ./sim <#Cycles> 152 | - Use a comma delimited list; no space; can be surrounded by brackets ()[]{}<> 153 | - CAM depth, pattern width, segment width and cycles are positive integers 154 | EXAMPLES: 155 | ./sim 8192 9 8 1000000 156 | Simulate 1M cycles of a 8K lines CAM, 9 bits pattern width, 8 bits segments 157 | ./sim 2048,4096 8,9,10 8,16 1000000 158 | Simulate 1M cycles of CAMs with 2k or 4k lines, 8, 9, or 10 bits pattern, 159 | 8 or 16 bits segment. Total of 12 CAM combinations 160 | The following files and directories will be created after simulation: 161 | - sim.res : A list of simulation results, each run in a separate line, 162 | including all design styles. 163 | EOH 164 | printf '\x1b[0m' 165 | scriptEnd: 166 | 167 | -------------------------------------------------------------------------------- /spram.v: -------------------------------------------------------------------------------- 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 | // spram.v: Generic single port RAM // 29 | // // 30 | // Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 32 | //////////////////////////////////////////////////////////////////////////////////// 33 | 34 | `include "utils.vh" 35 | 36 | module spram 37 | #( parameter MEMD = 512, // memory depth 38 | parameter DATAW = 32 , // data width 39 | parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over IFILE) 40 | parameter IFILE = "" ) // initialization hex file (don't pass extension), optional 41 | ( input clk , // clock 42 | input wEnb , // write enable for port B 43 | input [`log2(MEMD)-1:0] addr , // write/read address 44 | input [DATAW -1:0] wData, // write data 45 | output reg [DATAW -1:0] rData); // read data 46 | 47 | // initialize RAM, with zeros if IZERO or file if IFLE. 48 | integer i; 49 | reg [DATAW-1:0] mem [0:MEMD-1]; // memory array 50 | initial 51 | if (IZERO) 52 | for (i=0; i=64) 38 | parameter CAMW = 9 , // CAM/pattern width / for one stage (<=14) 39 | parameter INOM = 1 , // binary / Initial CAM with no match 40 | parameter BRAM = "M20K") // BRAM type- "M20K":Altera's M20K; "GEN":generic 41 | ( input clk , // clock 42 | input rst , // global registers reset 43 | input wEnb , // write enable 44 | input wrEr , // Write or erase (inverted) 45 | input [`log2(CAMD)-1:0] wAddr , // write address 46 | input [ CAMW -1:0] wPatt , // write pattern 47 | input [ CAMW -1:0] mPatt , // patern to match 48 | output [ CAMD -1:0] match ); // match / one-hot 49 | 50 | 51 | // Altera's M20K parameters 52 | localparam M20K_nBITS = 16384 ; // total bits 53 | localparam M20K_MIND = 512 ; // minimum depth / widest configuration 54 | localparam M20K_MINAW = `log2(M20K_MIND) ; // minimum address width (=9) 55 | localparam M20K_CAMW = (CAMW= M20K_MINAW (14) 56 | localparam M20K_DW = (M20K_nBITS/(2**M20K_CAMW))<1 ? 1 : (M20K_nBITS/(2**M20K_CAMW)) ; // M20K data width (=1) 57 | localparam nM20K = CAMD / M20K_DW ; // M20K count (32k) 58 | 59 | wire [`log2(CAMD)-`log2(M20K_DW)-1:0] M20KSel_bin = wAddr[`log2(CAMD)-1:`log2(M20K_DW)]; 60 | reg [nM20K -1:0] M20KSel_1ht ; 61 | // binary to one-hot 62 | always @(*) begin 63 | M20KSel_1ht = 0 ; 64 | M20KSel_1ht[M20KSel_bin] = wEnb; 65 | end 66 | 67 | // generate and instantiate mixed-width BRAMs 68 | genvar gi; 69 | generate 70 | if (BRAM=="M20K") 71 | for (gi=1 ; gi<=nM20K ; gi=gi+1) begin: BRAMgi 72 | if (CAMW<14) // M20K 73 | mwram_m20k #( .WR_DW( 1 ), // write width 74 | .RD_DW( M20K_DW ), // read width 75 | .IZERO( INOM )) // initialize to zeros 76 | mwram_m20k_i ( .clk ( clk ), // clock 77 | .rst ( rst ), // global registers reset 78 | .wEnb ( M20KSel_1ht[gi-1] ), // write enable 79 | .wAddr( {`ZPAD(wPatt,M20K_MINAW),wAddr[`log2(M20K_DW)-1:0]} ), // write address [13:0] 80 | .wData( wrEr ), // write data 81 | .rAddr( `ZPAD(mPatt,M20K_MINAW) ), // read address [ 8:0] 82 | .rData( match[gi*M20K_DW-1 -: M20K_DW]) ); // read data [31:0] 83 | else if (CAMW==14) // single bit read/write M20K 84 | mwram_m20k #( .WR_DW( 1 ), // write width 85 | .RD_DW( 1 ), // read width 86 | .IZERO( INOM )) // initialize to zeros 87 | mwram_m20k_i ( .clk ( clk ), // clock 88 | .rst ( rst ), // global registers reset 89 | .wEnb (M20KSel_1ht[gi-1] ), // write enable 90 | .wAddr( wPatt ), // write address [13:0] 91 | .wData( wrEr ), // write data 92 | .rAddr( mPatt ), // read address [ 8:0] 93 | .rData( match[gi-1]) ); // read data [31:0] 94 | else // CAMW>14 95 | sbram_m20k #( .DEPTH( 2**CAMW ), // RAM depth 96 | .IZERO( INOM )) // initialize to zeros 97 | sbram_m20k_i ( .clk ( clk ), // clock 98 | .rst ( rst ), // global registers reset 99 | .wEnb ( M20KSel_1ht[gi-1] ), // write enable 100 | .wAddr( wPatt ), // write address / [`log2(RD_D*RD_DW/WR_DW)-1:0] 101 | .wData( wrEr ), // write data / [WR_DW -1:0] 102 | .rAddr( mPatt ), // read address / [`log2(RD_D) -1:0] 103 | .rData( match[gi-1] )); // read data / [RD_DW -1:0] 104 | end 105 | else // generic 106 | mwram_gen #( .WR_DW( 1 ), // write data width 107 | .RD_DW( CAMD ), // read data width 108 | .RD_D ( 2**CAMW ), // read depth 109 | .IZERO( INOM )) // initialize to zeros 110 | mwram_gen_i ( .clk ( clk ), // clock 111 | .rst ( rst ), // global registers reset 112 | .wEnb ( wEnb ), // write enable 113 | .wAddr( {wPatt,wAddr} ), // write address / [`log2(RD_D*RD_DW/WR_DW)-1:0] 114 | .wData( wrEr ), // write data / [WR_DW -1:0] 115 | .rAddr( mPatt ), // read address / [`log2(RD_D) -1:0] 116 | .rData( match )); // read data / [RD_DW -1:0] 117 | endgenerate 118 | 119 | endmodule 120 | -------------------------------------------------------------------------------- /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.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) // 31 | // SRAM-based 2D BCAM; The University of British Columbia (UBC), April 2014 // 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 | // MAX and MIN 54 | `define MAX(SRCA,SRCB) ( ((SRCA)>(SRCB)) ? (SRCA) : (SRCB) ) 55 | `define MIN(SRCA,SRCB) ( ((SRCA)<(SRCB)) ? (SRCA) : (SRCB) ) 56 | 57 | // Zero padding 58 | `define ZPAD(SRC,DSTW) ( {(DSTW){1'b0}} | SRC ) 59 | 60 | // factorial (n!) 61 | `define fact(n) ( ( ((n) >= 2 ) ? 2 : 1) * \ 62 | ( ((n) >= 3 ) ? 3 : 1) * \ 63 | ( ((n) >= 4 ) ? 4 : 1) * \ 64 | ( ((n) >= 5 ) ? 5 : 1) * \ 65 | ( ((n) >= 6 ) ? 6 : 1) * \ 66 | ( ((n) >= 7 ) ? 7 : 1) * \ 67 | ( ((n) >= 8 ) ? 8 : 1) * \ 68 | ( ((n) >= 9 ) ? 9 : 1) * \ 69 | ( ((n) >= 10 ) ? 10 : 1) ) 70 | 71 | // ceiling of log2 72 | `define log2(x) ( ( ((x) > 1 ) ? 1 : 0) + \ 73 | ( ((x) > 2 ) ? 1 : 0) + \ 74 | ( ((x) > 4 ) ? 1 : 0) + \ 75 | ( ((x) > 8 ) ? 1 : 0) + \ 76 | ( ((x) > 16 ) ? 1 : 0) + \ 77 | ( ((x) > 32 ) ? 1 : 0) + \ 78 | ( ((x) > 64 ) ? 1 : 0) + \ 79 | ( ((x) > 128 ) ? 1 : 0) + \ 80 | ( ((x) > 256 ) ? 1 : 0) + \ 81 | ( ((x) > 512 ) ? 1 : 0) + \ 82 | ( ((x) > 1024 ) ? 1 : 0) + \ 83 | ( ((x) > 2048 ) ? 1 : 0) + \ 84 | ( ((x) > 4096 ) ? 1 : 0) + \ 85 | ( ((x) > 8192 ) ? 1 : 0) + \ 86 | ( ((x) > 16384 ) ? 1 : 0) + \ 87 | ( ((x) > 32768 ) ? 1 : 0) + \ 88 | ( ((x) > 65536 ) ? 1 : 0) + \ 89 | ( ((x) > 131072 ) ? 1 : 0) + \ 90 | ( ((x) > 262144 ) ? 1 : 0) + \ 91 | ( ((x) > 524288 ) ? 1 : 0) + \ 92 | ( ((x) > 1048576) ? 1 : 0) + \ 93 | ( ((x) > 2097152) ? 1 : 0) + \ 94 | ( ((x) > 4194304) ? 1 : 0) ) 95 | 96 | // floor of log2 97 | `define log2f(x) ( ( ((x) >= 2 ) ? 1 : 0) + \ 98 | ( ((x) >= 4 ) ? 1 : 0) + \ 99 | ( ((x) >= 8 ) ? 1 : 0) + \ 100 | ( ((x) >= 16 ) ? 1 : 0) + \ 101 | ( ((x) >= 32 ) ? 1 : 0) + \ 102 | ( ((x) >= 64 ) ? 1 : 0) + \ 103 | ( ((x) >= 128 ) ? 1 : 0) + \ 104 | ( ((x) >= 256 ) ? 1 : 0) + \ 105 | ( ((x) >= 512 ) ? 1 : 0) + \ 106 | ( ((x) >= 1024 ) ? 1 : 0) + \ 107 | ( ((x) >= 2048 ) ? 1 : 0) + \ 108 | ( ((x) >= 4096 ) ? 1 : 0) + \ 109 | ( ((x) >= 8192 ) ? 1 : 0) + \ 110 | ( ((x) >= 16384 ) ? 1 : 0) + \ 111 | ( ((x) >= 32768 ) ? 1 : 0) + \ 112 | ( ((x) >= 65536 ) ? 1 : 0) + \ 113 | ( ((x) >= 131072 ) ? 1 : 0) + \ 114 | ( ((x) >= 262144 ) ? 1 : 0) + \ 115 | ( ((x) >= 524288 ) ? 1 : 0) + \ 116 | ( ((x) >= 1048576) ? 1 : 0) + \ 117 | ( ((x) >= 2097152) ? 1 : 0) + \ 118 | ( ((x) >= 4194304) ? 1 : 0) ) 119 | 120 | `endif //__UTILS_VH__ 121 | --------------------------------------------------------------------------------