| 1 | ////////////////////////////////////////////////////////////////////// |
| 2 | //// //// |
| 3 | //// File name: decoder.v //// |
| 4 | //// //// |
| 5 | //// This file is part of the "PCI bridge" project //// |
| 6 | //// http://www.opencores.org/cores/pci/ //// |
| 7 | //// //// |
| 8 | //// Author(s): //// |
| 9 | //// - Tadej Markovic, tadej@opencores.org //// |
| 10 | //// - Tilen Novak, tilen@opencores.org //// |
| 11 | //// //// |
| 12 | //// All additional information is avaliable in the README.txt //// |
| 13 | //// file. //// |
| 14 | //// //// |
| 15 | //// //// |
| 16 | ////////////////////////////////////////////////////////////////////// |
| 17 | //// //// |
| 18 | //// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
| 19 | //// Tilen Novak, tilen@opencores.org //// |
| 20 | //// //// |
| 21 | //// This source file may be used and distributed without //// |
| 22 | //// restriction provided that this copyright statement is not //// |
| 23 | //// removed from the file and that any derivative work contains //// |
| 24 | //// the original copyright notice and the associated disclaimer. //// |
| 25 | //// //// |
| 26 | //// This source file is free software; you can redistribute it //// |
| 27 | //// and/or modify it under the terms of the GNU Lesser General //// |
| 28 | //// Public License as published by the Free Software Foundation; //// |
| 29 | //// either version 2.1 of the License, or (at your option) any //// |
| 30 | //// later version. //// |
| 31 | //// //// |
| 32 | //// This source is distributed in the hope that it will be //// |
| 33 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
| 34 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
| 35 | //// PURPOSE. See the GNU Lesser General Public License for more //// |
| 36 | //// details. //// |
| 37 | //// //// |
| 38 | //// You should have received a copy of the GNU Lesser General //// |
| 39 | //// Public License along with this source; if not, download it //// |
| 40 | //// from http://www.opencores.org/lgpl.shtml //// |
| 41 | //// //// |
| 42 | ////////////////////////////////////////////////////////////////////// |
| 43 | // |
| 44 | // CVS Revision History |
| 45 | // |
| 46 | // $Log: pci_wb_decoder.v,v $ |
| 47 | // Revision 1.1 2007-03-20 17:50:56 sithglan |
| 48 | // add shit |
| 49 | // |
| 50 | // Revision 1.1 2003/01/27 16:49:31 mihad |
| 51 | // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
| 52 | // |
| 53 | // Revision 1.3 2002/02/01 15:25:12 mihad |
| 54 | // Repaired a few bugs, updated specification, added test bench files and design document |
| 55 | // |
| 56 | // Revision 1.2 2001/10/05 08:14:28 mihad |
| 57 | // Updated all files with inclusion of timescale file for simulation purposes. |
| 58 | // |
| 59 | // Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
| 60 | // New project directory structure |
| 61 | // |
| 62 | // |
| 63 | |
| 64 | `include "pci_constants.v" |
| 65 | |
| 66 | // synopsys translate_off |
| 67 | `include "timescale.v" |
| 68 | // synopsys translate_on |
| 69 | |
| 70 | module pci_wb_decoder (hit, addr_out, addr_in, base_addr, mask_addr, tran_addr, at_en) ; |
| 71 | |
| 72 | // Decoding address size parameter - for FPGAs 1MegByte is recommended |
| 73 | // MAXIMUM is 20 (4KBytes), length 12 is 1 MByte !!! |
| 74 | parameter decode_len = 12 ; |
| 75 | |
| 76 | //########################################################################################################### |
| 77 | // ALL COMMENTS are written as there were decode_len 20. This number and 12 (32 - 20) are assigning the |
| 78 | // numbers of decoded and compared bits, etc. |
| 79 | //########################################################################################################### |
| 80 | |
| 81 | /*----------------------------------------------------------------------------------------------------------- |
| 82 | DECODER interface decodes input address (ADDR_IN); what means that it validates (HIT), if input address |
| 83 | falls within the defined image space boundaries. Image space boundarie is defined with image base address |
| 84 | register (BASE_ADDR) and address mask register (MASK_ADDR). |
| 85 | Beside that, it also translates (maps) the input address to the output address (ADDR_OUT), regarding the |
| 86 | translation address register (TRAN_ADDR) and the address mask register. |
| 87 | -----------------------------------------------------------------------------------------------------------*/ |
| 88 | |
| 89 | // output control |
| 90 | output hit ; |
| 91 | // output address |
| 92 | output [31:0] addr_out ; |
| 93 | // input address |
| 94 | input [31:0] addr_in ; |
| 95 | |
| 96 | // input registers - 12 LSbits are not valid since the smallest possible size is 4KB ! |
| 97 | input [31:(32-decode_len)] base_addr ; |
| 98 | input [31:(32-decode_len)] mask_addr ; |
| 99 | input [31:(32-decode_len)] tran_addr ; |
| 100 | |
| 101 | // input bit[2] of the Image Control register used to enable the address translation ! |
| 102 | input at_en ; |
| 103 | /*----------------------------------------------------------------------------------------------------------- |
| 104 | Internal signals ! |
| 105 | -----------------------------------------------------------------------------------------------------------*/ |
| 106 | |
| 107 | // bit[31] if address mask register is IMAGE ENABLE bit (img_en) |
| 108 | wire img_en ; |
| 109 | |
| 110 | // addr_in_compare are masked input address bits that are compared with masked base_addr |
| 111 | wire [31:(32-decode_len)] addr_in_compare ; |
| 112 | // base_addr_compare are masked base address bits that are compared with masked addr_in |
| 113 | wire [31:(32-decode_len)] base_addr_compare ; |
| 114 | |
| 115 | /*----------------------------------------------------------------------------------------------------------- |
| 116 | Decoding the input address! |
| 117 | This logic produces the loghest path in this module! |
| 118 | |
| 119 | 20 MSbits of input addres are as well as base address (20 bits) masked with corrected address mask. Only |
| 120 | masked bits of each vector are actually logically compared. |
| 121 | Bit[31] of address mask register is used to enable the image space ! |
| 122 | -----------------------------------------------------------------------------------------------------------*/ |
| 123 | |
| 124 | assign addr_in_compare = (addr_in[31:(32-decode_len)] & mask_addr) ; |
| 125 | |
| 126 | assign base_addr_compare = (base_addr & mask_addr) ; |
| 127 | |
| 128 | assign img_en = mask_addr[31] ; |
| 129 | |
| 130 | assign hit = { 1'b1, addr_in_compare } == { img_en, base_addr_compare } ; |
| 131 | |
| 132 | /*----------------------------------------------------------------------------------------------------------- |
| 133 | Translating the input address! |
| 134 | |
| 135 | Translation of input address is not implemented if ADDR_TRAN_IMPL is not defined |
| 136 | |
| 137 | 20 MSbits of input address are masked with negated value of the corrected address mask in order to get |
| 138 | address bits of the input address which won't be replaced with translation address bits. |
| 139 | Translation address bits (20 bits) are masked with corrected address mask. Only masked bits of vector are |
| 140 | actually valid, all others are zero. |
| 141 | Boath vectors are bit-wise ORed in order to get the valid translation address with an offset of an input |
| 142 | address. |
| 143 | 12 LSbits of an input address are assigned to 12 LSbits of an output addres. |
| 144 | -----------------------------------------------------------------------------------------------------------*/ |
| 145 | |
| 146 | `ifdef ADDR_TRAN_IMPL |
| 147 | // if Address Translation Enable bit is set, then translation address is used othervise input address is used! |
| 148 | // addr_in_combine input address bits are not replaced with translation address! |
| 149 | wire [31:(32-decode_len)] addr_in_combine ; |
| 150 | // tran_addr_combine are masked and combined with addr_in_combine! |
| 151 | reg [31:(32-decode_len)] tran_addr_combine ; |
| 152 | |
| 153 | assign addr_in_combine = (addr_in[31:(32-decode_len)] & ~mask_addr) ; |
| 154 | always@(at_en or tran_addr or mask_addr or addr_in) |
| 155 | begin |
| 156 | if (at_en) |
| 157 | begin |
| 158 | tran_addr_combine <= (tran_addr & mask_addr) ; |
| 159 | end |
| 160 | else |
| 161 | begin |
| 162 | tran_addr_combine <= (addr_in[31:(32-decode_len)] & mask_addr) ; |
| 163 | end |
| 164 | end |
| 165 | |
| 166 | assign addr_out[31:(32-decode_len)] = addr_in_combine | tran_addr_combine ; |
| 167 | assign addr_out[(31-decode_len):0] = addr_in [(31-decode_len):0] ; |
| 168 | `else |
| 169 | assign addr_out = addr_in ; |
| 170 | `endif |
| 171 | |
| 172 | endmodule |
| 173 | |