| 1 | 221 | olivier.gi | //----------------------------------------------------------------------------
 | 
      
         | 2 |  |  | // Copyright (C) 2009 , Olivier Girard
 | 
      
         | 3 |  |  | //
 | 
      
         | 4 |  |  | // Redistribution and use in source and binary forms, with or without
 | 
      
         | 5 |  |  | // modification, are permitted provided that the following conditions
 | 
      
         | 6 |  |  | // are met:
 | 
      
         | 7 |  |  | //     * Redistributions of source code must retain the above copyright
 | 
      
         | 8 |  |  | //       notice, this list of conditions and the following disclaimer.
 | 
      
         | 9 |  |  | //     * Redistributions in binary form must reproduce the above copyright
 | 
      
         | 10 |  |  | //       notice, this list of conditions and the following disclaimer in the
 | 
      
         | 11 |  |  | //       documentation and/or other materials provided with the distribution.
 | 
      
         | 12 |  |  | //     * Neither the name of the authors nor the names of its contributors
 | 
      
         | 13 |  |  | //       may be used to endorse or promote products derived from this software
 | 
      
         | 14 |  |  | //       without specific prior written permission.
 | 
      
         | 15 |  |  | //
 | 
      
         | 16 |  |  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
      
         | 17 |  |  | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
      
         | 18 |  |  | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
      
         | 19 |  |  | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 | 
      
         | 20 |  |  | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 | 
      
         | 21 |  |  | // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
      
         | 22 |  |  | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
      
         | 23 |  |  | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
      
         | 24 |  |  | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
      
         | 25 |  |  | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
      
         | 26 |  |  | // THE POSSIBILITY OF SUCH DAMAGE
 | 
      
         | 27 |  |  | //
 | 
      
         | 28 |  |  | //----------------------------------------------------------------------------
 | 
      
         | 29 |  |  | //
 | 
      
         | 30 |  |  | // *File Name: omsp_mem_backbone.v
 | 
      
         | 31 |  |  | //
 | 
      
         | 32 |  |  | // *Module Description:
 | 
      
         | 33 |  |  | //                       Memory interface backbone (decoder + arbiter)
 | 
      
         | 34 |  |  | //
 | 
      
         | 35 |  |  | // *Author(s):
 | 
      
         | 36 |  |  | //              - Olivier Girard,    olgirard@gmail.com
 | 
      
         | 37 |  |  | //
 | 
      
         | 38 |  |  | //----------------------------------------------------------------------------
 | 
      
         | 39 |  |  | // $Rev: 103 $
 | 
      
         | 40 |  |  | // $LastChangedBy: olivier.girard $
 | 
      
         | 41 |  |  | // $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
 | 
      
         | 42 |  |  | //----------------------------------------------------------------------------
 | 
      
         | 43 |  |  | `ifdef OMSP_NO_INCLUDE
 | 
      
         | 44 |  |  | `else
 | 
      
         | 45 |  |  | `include "openMSP430_defines.v"
 | 
      
         | 46 |  |  | `endif
 | 
      
         | 47 |  |  |  
 | 
      
         | 48 |  |  | module  omsp_mem_backbone (
 | 
      
         | 49 |  |  |  
 | 
      
         | 50 |  |  | // OUTPUTs
 | 
      
         | 51 |  |  |     cpu_halt_cmd,                       // Halt CPU command
 | 
      
         | 52 |  |  |     dbg_mem_din,                        // Debug unit Memory data input
 | 
      
         | 53 |  |  |     dmem_addr,                          // Data Memory address
 | 
      
         | 54 |  |  |     dmem_cen,                           // Data Memory chip enable (low active)
 | 
      
         | 55 |  |  |     dmem_din,                           // Data Memory data input
 | 
      
         | 56 |  |  |     dmem_wen,                           // Data Memory write enable (low active)
 | 
      
         | 57 |  |  |     eu_mdb_in,                          // Execution Unit Memory data bus input
 | 
      
         | 58 |  |  |     fe_mdb_in,                          // Frontend Memory data bus input
 | 
      
         | 59 |  |  |     fe_pmem_wait,                       // Frontend wait for Instruction fetch
 | 
      
         | 60 |  |  |     dma_dout,                           // Direct Memory Access data output
 | 
      
         | 61 |  |  |     dma_ready,                          // Direct Memory Access is complete
 | 
      
         | 62 |  |  |     dma_resp,                           // Direct Memory Access response (0:Okay / 1:Error)
 | 
      
         | 63 |  |  |     per_addr,                           // Peripheral address
 | 
      
         | 64 |  |  |     per_din,                            // Peripheral data input
 | 
      
         | 65 |  |  |     per_we,                             // Peripheral write enable (high active)
 | 
      
         | 66 |  |  |     per_en,                             // Peripheral enable (high active)
 | 
      
         | 67 |  |  |     pmem_addr,                          // Program Memory address
 | 
      
         | 68 |  |  |     pmem_cen,                           // Program Memory chip enable (low active)
 | 
      
         | 69 |  |  |     pmem_din,                           // Program Memory data input (optional)
 | 
      
         | 70 |  |  |     pmem_wen,                           // Program Memory write enable (low active) (optional)
 | 
      
         | 71 |  |  |  
 | 
      
         | 72 |  |  | // INPUTs
 | 
      
         | 73 |  |  |     cpu_halt_st,                        // Halt/Run status from CPU
 | 
      
         | 74 |  |  |     dbg_halt_cmd,                       // Debug interface Halt CPU command
 | 
      
         | 75 |  |  |     dbg_mem_addr,                       // Debug address for rd/wr access
 | 
      
         | 76 |  |  |     dbg_mem_dout,                       // Debug unit data output
 | 
      
         | 77 |  |  |     dbg_mem_en,                         // Debug unit memory enable
 | 
      
         | 78 |  |  |     dbg_mem_wr,                         // Debug unit memory write
 | 
      
         | 79 |  |  |     dmem_dout,                          // Data Memory data output
 | 
      
         | 80 |  |  |     eu_mab,                             // Execution Unit Memory address bus
 | 
      
         | 81 |  |  |     eu_mb_en,                           // Execution Unit Memory bus enable
 | 
      
         | 82 |  |  |     eu_mb_wr,                           // Execution Unit Memory bus write transfer
 | 
      
         | 83 |  |  |     eu_mdb_out,                         // Execution Unit Memory data bus output
 | 
      
         | 84 |  |  |     fe_mab,                             // Frontend Memory address bus
 | 
      
         | 85 |  |  |     fe_mb_en,                           // Frontend Memory bus enable
 | 
      
         | 86 |  |  |     mclk,                               // Main system clock
 | 
      
         | 87 |  |  |     dma_addr,                           // Direct Memory Access address
 | 
      
         | 88 |  |  |     dma_din,                            // Direct Memory Access data input
 | 
      
         | 89 |  |  |     dma_en,                             // Direct Memory Access enable (high active)
 | 
      
         | 90 |  |  |     dma_priority,                       // Direct Memory Access priority (0:low / 1:high)
 | 
      
         | 91 |  |  |     dma_we,                             // Direct Memory Access write byte enable (high active)
 | 
      
         | 92 |  |  |     per_dout,                           // Peripheral data output
 | 
      
         | 93 |  |  |     pmem_dout,                          // Program Memory data output
 | 
      
         | 94 |  |  |     puc_rst,                            // Main system reset
 | 
      
         | 95 |  |  |     scan_enable                         // Scan enable (active during scan shifting)
 | 
      
         | 96 |  |  | );
 | 
      
         | 97 |  |  |  
 | 
      
         | 98 |  |  | // OUTPUTs
 | 
      
         | 99 |  |  | //=========
 | 
      
         | 100 |  |  | output               cpu_halt_cmd;      // Halt CPU command
 | 
      
         | 101 |  |  | output        [15:0] dbg_mem_din;       // Debug unit Memory data input
 | 
      
         | 102 |  |  | output [`DMEM_MSB:0] dmem_addr;         // Data Memory address
 | 
      
         | 103 |  |  | output               dmem_cen;          // Data Memory chip enable (low active)
 | 
      
         | 104 |  |  | output        [15:0] dmem_din;          // Data Memory data input
 | 
      
         | 105 |  |  | output         [1:0] dmem_wen;          // Data Memory write enable (low active)
 | 
      
         | 106 |  |  | output        [15:0] eu_mdb_in;         // Execution Unit Memory data bus input
 | 
      
         | 107 |  |  | output        [15:0] fe_mdb_in;         // Frontend Memory data bus input
 | 
      
         | 108 |  |  | output               fe_pmem_wait;      // Frontend wait for Instruction fetch
 | 
      
         | 109 |  |  | output        [15:0] dma_dout;          // Direct Memory Access data output
 | 
      
         | 110 |  |  | output               dma_ready;         // Direct Memory Access is complete
 | 
      
         | 111 |  |  | output               dma_resp;          // Direct Memory Access response (0:Okay / 1:Error)
 | 
      
         | 112 |  |  | output        [13:0] per_addr;          // Peripheral address
 | 
      
         | 113 |  |  | output        [15:0] per_din;           // Peripheral data input
 | 
      
         | 114 |  |  | output         [1:0] per_we;            // Peripheral write enable (high active)
 | 
      
         | 115 |  |  | output               per_en;            // Peripheral enable (high active)
 | 
      
         | 116 |  |  | output [`PMEM_MSB:0] pmem_addr;         // Program Memory address
 | 
      
         | 117 |  |  | output               pmem_cen;          // Program Memory chip enable (low active)
 | 
      
         | 118 |  |  | output        [15:0] pmem_din;          // Program Memory data input (optional)
 | 
      
         | 119 |  |  | output         [1:0] pmem_wen;          // Program Memory write enable (low active) (optional)
 | 
      
         | 120 |  |  |  
 | 
      
         | 121 |  |  | // INPUTs
 | 
      
         | 122 |  |  | //=========
 | 
      
         | 123 |  |  | input                cpu_halt_st;       // Halt/Run status from CPU
 | 
      
         | 124 |  |  | input                dbg_halt_cmd;      // Debug interface Halt CPU command
 | 
      
         | 125 |  |  | input         [15:1] dbg_mem_addr;      // Debug address for rd/wr access
 | 
      
         | 126 |  |  | input         [15:0] dbg_mem_dout;      // Debug unit data output
 | 
      
         | 127 |  |  | input                dbg_mem_en;        // Debug unit memory enable
 | 
      
         | 128 |  |  | input          [1:0] dbg_mem_wr;        // Debug unit memory write
 | 
      
         | 129 |  |  | input         [15:0] dmem_dout;         // Data Memory data output
 | 
      
         | 130 |  |  | input         [14:0] eu_mab;            // Execution Unit Memory address bus
 | 
      
         | 131 |  |  | input                eu_mb_en;          // Execution Unit Memory bus enable
 | 
      
         | 132 |  |  | input          [1:0] eu_mb_wr;          // Execution Unit Memory bus write transfer
 | 
      
         | 133 |  |  | input         [15:0] eu_mdb_out;        // Execution Unit Memory data bus output
 | 
      
         | 134 |  |  | input         [14:0] fe_mab;            // Frontend Memory address bus
 | 
      
         | 135 |  |  | input                fe_mb_en;          // Frontend Memory bus enable
 | 
      
         | 136 |  |  | input                mclk;              // Main system clock
 | 
      
         | 137 |  |  | input         [15:1] dma_addr;          // Direct Memory Access address
 | 
      
         | 138 |  |  | input         [15:0] dma_din;           // Direct Memory Access data input
 | 
      
         | 139 |  |  | input                dma_en;            // Direct Memory Access enable (high active)
 | 
      
         | 140 |  |  | input                dma_priority;      // Direct Memory Access priority (0:low / 1:high)
 | 
      
         | 141 |  |  | input          [1:0] dma_we;            // Direct Memory Access write byte enable (high active)
 | 
      
         | 142 |  |  | input         [15:0] per_dout;          // Peripheral data output
 | 
      
         | 143 |  |  | input         [15:0] pmem_dout;         // Program Memory data output
 | 
      
         | 144 |  |  | input                puc_rst;           // Main system reset
 | 
      
         | 145 |  |  | input                scan_enable;       // Scan enable (active during scan shifting)
 | 
      
         | 146 |  |  |  
 | 
      
         | 147 |  |  | wire                 ext_mem_en;
 | 
      
         | 148 |  |  | wire          [15:0] ext_mem_din;
 | 
      
         | 149 |  |  | wire                 ext_dmem_sel;
 | 
      
         | 150 |  |  | wire                 ext_dmem_en;
 | 
      
         | 151 |  |  | wire                 ext_pmem_sel;
 | 
      
         | 152 |  |  | wire                 ext_pmem_en;
 | 
      
         | 153 |  |  | wire                 ext_per_sel;
 | 
      
         | 154 |  |  | wire                 ext_per_en;
 | 
      
         | 155 |  |  |  
 | 
      
         | 156 |  |  |  
 | 
      
         | 157 |  |  | //=============================================================================
 | 
      
         | 158 |  |  | // 1)  DECODER
 | 
      
         | 159 |  |  | //=============================================================================
 | 
      
         | 160 |  |  |  
 | 
      
         | 161 |  |  | //------------------------------------------
 | 
      
         | 162 |  |  | // Arbiter between DMA and Debug interface
 | 
      
         | 163 |  |  | //------------------------------------------
 | 
      
         | 164 |  |  | `ifdef DMA_IF_EN
 | 
      
         | 165 |  |  |  
 | 
      
         | 166 |  |  | // Debug-interface always stops the CPU
 | 
      
         | 167 |  |  | // Master interface stops the CPU in priority mode
 | 
      
         | 168 |  |  | assign      cpu_halt_cmd  =  dbg_halt_cmd | (dma_en & dma_priority);
 | 
      
         | 169 |  |  |  
 | 
      
         | 170 |  |  | // Return ERROR response if address lays outside the memory spaces (Peripheral, Data & Program memories)
 | 
      
         | 171 |  |  | assign      dma_resp      = ~dbg_mem_en & ~(ext_dmem_sel | ext_pmem_sel | ext_per_sel) & dma_en;
 | 
      
         | 172 |  |  |  
 | 
      
         | 173 |  |  | // Master interface access is ready when the memory access occures
 | 
      
         | 174 |  |  | assign      dma_ready     = ~dbg_mem_en &  (ext_dmem_en  | ext_pmem_en  | ext_per_en | dma_resp);
 | 
      
         | 175 |  |  |  
 | 
      
         | 176 |  |  | // Use delayed version of 'dma_ready' to mask the 'dma_dout' data output
 | 
      
         | 177 |  |  | // when not accessed and reduce toggle rate (thus power consumption)
 | 
      
         | 178 |  |  | reg         dma_ready_dly;
 | 
      
         | 179 |  |  | always @ (posedge mclk or posedge puc_rst)
 | 
      
         | 180 |  |  |   if (puc_rst)  dma_ready_dly <=  1'b0;
 | 
      
         | 181 |  |  |   else          dma_ready_dly <=  dma_ready;
 | 
      
         | 182 |  |  |  
 | 
      
         | 183 |  |  | // Mux between debug and master interface
 | 
      
         | 184 |  |  | assign      ext_mem_en    =  dbg_mem_en | dma_en;
 | 
      
         | 185 |  |  | wire  [1:0] ext_mem_wr    =  dbg_mem_en ? dbg_mem_wr    :  dma_we;
 | 
      
         | 186 |  |  | wire [15:1] ext_mem_addr  =  dbg_mem_en ? dbg_mem_addr  :  dma_addr;
 | 
      
         | 187 |  |  | wire [15:0] ext_mem_dout  =  dbg_mem_en ? dbg_mem_dout  :  dma_din;
 | 
      
         | 188 |  |  |  
 | 
      
         | 189 |  |  | // External interface read data
 | 
      
         | 190 |  |  | assign      dbg_mem_din   =  ext_mem_din;
 | 
      
         | 191 |  |  | assign      dma_dout      =  ext_mem_din & {16{dma_ready_dly}};
 | 
      
         | 192 |  |  |  
 | 
      
         | 193 |  |  |  
 | 
      
         | 194 |  |  | `else
 | 
      
         | 195 |  |  | // Debug-interface always stops the CPU
 | 
      
         | 196 |  |  | assign      cpu_halt_cmd  =  dbg_halt_cmd;
 | 
      
         | 197 |  |  |  
 | 
      
         | 198 |  |  | // Master interface access is always ready with error response when excluded
 | 
      
         | 199 |  |  | assign      dma_resp      =  1'b1;
 | 
      
         | 200 |  |  | assign      dma_ready     =  1'b1;
 | 
      
         | 201 |  |  |  
 | 
      
         | 202 |  |  | // Debug interface only
 | 
      
         | 203 |  |  | assign      ext_mem_en    =  dbg_mem_en;
 | 
      
         | 204 |  |  | wire  [1:0] ext_mem_wr    =  dbg_mem_wr;
 | 
      
         | 205 |  |  | wire [15:1] ext_mem_addr  =  dbg_mem_addr;
 | 
      
         | 206 |  |  | wire [15:0] ext_mem_dout  =  dbg_mem_dout;
 | 
      
         | 207 |  |  |  
 | 
      
         | 208 |  |  | // External interface read data
 | 
      
         | 209 |  |  | assign      dbg_mem_din   =  ext_mem_din;
 | 
      
         | 210 |  |  | assign      dma_dout      =  16'h0000;
 | 
      
         | 211 |  |  |  
 | 
      
         | 212 |  |  | // LINT Cleanup
 | 
      
         | 213 |  |  | wire [15:1] UNUSED_dma_addr     = dma_addr;
 | 
      
         | 214 |  |  | wire [15:0] UNUSED_dma_din      = dma_din;
 | 
      
         | 215 |  |  | wire        UNUSED_dma_en       = dma_en;
 | 
      
         | 216 |  |  | wire        UNUSED_dma_priority = dma_priority;
 | 
      
         | 217 |  |  | wire  [1:0] UNUSED_dma_we       = dma_we;
 | 
      
         | 218 |  |  |  
 | 
      
         | 219 |  |  | `endif
 | 
      
         | 220 |  |  |  
 | 
      
         | 221 |  |  | //------------------------------------------
 | 
      
         | 222 |  |  | // DATA-MEMORY Interface
 | 
      
         | 223 |  |  | //------------------------------------------
 | 
      
         | 224 |  |  | parameter          DMEM_END      = `DMEM_BASE+`DMEM_SIZE;
 | 
      
         | 225 |  |  |  
 | 
      
         | 226 |  |  | // Execution unit access
 | 
      
         | 227 |  |  | wire               eu_dmem_sel   = (eu_mab>=(`DMEM_BASE>>1)) &
 | 
      
         | 228 |  |  |                                    (eu_mab< ( DMEM_END >>1));
 | 
      
         | 229 |  |  | wire               eu_dmem_en    = eu_mb_en & eu_dmem_sel;
 | 
      
         | 230 |  |  | wire        [15:0] eu_dmem_addr  = {1'b0, eu_mab}-(`DMEM_BASE>>1);
 | 
      
         | 231 |  |  |  
 | 
      
         | 232 |  |  | // Front-end access
 | 
      
         | 233 |  |  | // -- not allowed to execute from data memory --
 | 
      
         | 234 |  |  |  
 | 
      
         | 235 |  |  | // External Master/Debug interface access
 | 
      
         | 236 |  |  | assign             ext_dmem_sel  = (ext_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
 | 
      
         | 237 |  |  |                                    (ext_mem_addr[15:1]< ( DMEM_END >>1));
 | 
      
         | 238 |  |  | assign             ext_dmem_en   = ext_mem_en &  ext_dmem_sel & ~eu_dmem_en;
 | 
      
         | 239 |  |  | wire        [15:0] ext_dmem_addr = {1'b0, ext_mem_addr[15:1]}-(`DMEM_BASE>>1);
 | 
      
         | 240 |  |  |  
 | 
      
         | 241 |  |  |  
 | 
      
         | 242 |  |  | // Data-Memory Interface
 | 
      
         | 243 |  |  | wire               dmem_cen      = ~(ext_dmem_en | eu_dmem_en);
 | 
      
         | 244 |  |  | wire         [1:0] dmem_wen      =   ext_dmem_en ? ~ext_mem_wr                 : ~eu_mb_wr;
 | 
      
         | 245 |  |  | wire [`DMEM_MSB:0] dmem_addr     =   ext_dmem_en ?  ext_dmem_addr[`DMEM_MSB:0] :  eu_dmem_addr[`DMEM_MSB:0];
 | 
      
         | 246 |  |  | wire        [15:0] dmem_din      =   ext_dmem_en ?  ext_mem_dout               :  eu_mdb_out;
 | 
      
         | 247 |  |  |  
 | 
      
         | 248 |  |  |  
 | 
      
         | 249 |  |  | //------------------------------------------
 | 
      
         | 250 |  |  | // PROGRAM-MEMORY Interface
 | 
      
         | 251 |  |  | //------------------------------------------
 | 
      
         | 252 |  |  |  
 | 
      
         | 253 |  |  | parameter          PMEM_OFFSET   = (16'hFFFF-`PMEM_SIZE+1);
 | 
      
         | 254 |  |  |  
 | 
      
         | 255 |  |  | // Execution unit access (only read access are accepted)
 | 
      
         | 256 |  |  | wire               eu_pmem_sel   = (eu_mab>=(PMEM_OFFSET>>1));
 | 
      
         | 257 |  |  | wire               eu_pmem_en    = eu_mb_en & ~|eu_mb_wr & eu_pmem_sel;
 | 
      
         | 258 |  |  | wire        [15:0] eu_pmem_addr  = eu_mab-(PMEM_OFFSET>>1);
 | 
      
         | 259 |  |  |  
 | 
      
         | 260 |  |  | // Front-end access
 | 
      
         | 261 |  |  | wire               fe_pmem_sel   = (fe_mab>=(PMEM_OFFSET>>1));
 | 
      
         | 262 |  |  | wire               fe_pmem_en    = fe_mb_en & fe_pmem_sel;
 | 
      
         | 263 |  |  | wire        [15:0] fe_pmem_addr  = fe_mab-(PMEM_OFFSET>>1);
 | 
      
         | 264 |  |  |  
 | 
      
         | 265 |  |  | // External Master/Debug interface access
 | 
      
         | 266 |  |  | assign             ext_pmem_sel  = (ext_mem_addr[15:1]>=(PMEM_OFFSET>>1));
 | 
      
         | 267 |  |  | assign             ext_pmem_en   = ext_mem_en & ext_pmem_sel & ~eu_pmem_en & ~fe_pmem_en;
 | 
      
         | 268 |  |  | wire        [15:0] ext_pmem_addr = {1'b0, ext_mem_addr[15:1]}-(PMEM_OFFSET>>1);
 | 
      
         | 269 |  |  |  
 | 
      
         | 270 |  |  |  
 | 
      
         | 271 |  |  | // Program-Memory Interface (Execution unit has priority over the Front-end)
 | 
      
         | 272 |  |  | wire               pmem_cen      = ~(fe_pmem_en | eu_pmem_en | ext_pmem_en);
 | 
      
         | 273 |  |  | wire         [1:0] pmem_wen      =  ext_pmem_en ? ~ext_mem_wr                 : 2'b11;
 | 
      
         | 274 |  |  | wire [`PMEM_MSB:0] pmem_addr     =  ext_pmem_en ?  ext_pmem_addr[`PMEM_MSB:0] :
 | 
      
         | 275 |  |  |                                     eu_pmem_en  ?  eu_pmem_addr[`PMEM_MSB:0]  : fe_pmem_addr[`PMEM_MSB:0];
 | 
      
         | 276 |  |  | wire        [15:0] pmem_din      =  ext_mem_dout;
 | 
      
         | 277 |  |  |  
 | 
      
         | 278 |  |  | wire               fe_pmem_wait  = (fe_pmem_en & eu_pmem_en);
 | 
      
         | 279 |  |  |  
 | 
      
         | 280 |  |  |  
 | 
      
         | 281 |  |  | //------------------------------------------
 | 
      
         | 282 |  |  | // PERIPHERALS Interface
 | 
      
         | 283 |  |  | //------------------------------------------
 | 
      
         | 284 |  |  |  
 | 
      
         | 285 |  |  | // Execution unit access
 | 
      
         | 286 |  |  | wire               eu_per_sel    =  (eu_mab<(`PER_SIZE>>1));
 | 
      
         | 287 |  |  | wire               eu_per_en     =  eu_mb_en & eu_per_sel;
 | 
      
         | 288 |  |  |  
 | 
      
         | 289 |  |  | // Front-end access
 | 
      
         | 290 |  |  | // -- not allowed to execute from peripherals memory space --
 | 
      
         | 291 |  |  |  
 | 
      
         | 292 |  |  | // External Master/Debug interface access
 | 
      
         | 293 |  |  | assign             ext_per_sel   =  (ext_mem_addr[15:1]<(`PER_SIZE>>1));
 | 
      
         | 294 |  |  | assign             ext_per_en    =  ext_mem_en & ext_per_sel & ~eu_per_en;
 | 
      
         | 295 |  |  |  
 | 
      
         | 296 |  |  | // Peripheral Interface
 | 
      
         | 297 |  |  | wire               per_en        =  ext_per_en | eu_per_en;
 | 
      
         | 298 |  |  | wire         [1:0] per_we        =  ext_per_en ? ext_mem_wr                 : eu_mb_wr;
 | 
      
         | 299 |  |  | wire  [`PER_MSB:0] per_addr_mux  =  ext_per_en ? ext_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
 | 
      
         | 300 |  |  | wire        [14:0] per_addr_ful  =  {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
 | 
      
         | 301 |  |  | wire        [13:0] per_addr      =  per_addr_ful[13:0];
 | 
      
         | 302 |  |  | wire        [15:0] per_din       =  ext_per_en ? ext_mem_dout               : eu_mdb_out;
 | 
      
         | 303 |  |  |  
 | 
      
         | 304 |  |  | // Register peripheral data read path
 | 
      
         | 305 |  |  | reg   [15:0] per_dout_val;
 | 
      
         | 306 |  |  | always @ (posedge mclk or posedge puc_rst)
 | 
      
         | 307 |  |  |   if (puc_rst)  per_dout_val    <=  16'h0000;
 | 
      
         | 308 |  |  |   else          per_dout_val    <=  per_dout;
 | 
      
         | 309 |  |  |  
 | 
      
         | 310 |  |  |  
 | 
      
         | 311 |  |  | //------------------------------------------
 | 
      
         | 312 |  |  | // Frontend data Mux
 | 
      
         | 313 |  |  | //------------------------------------------
 | 
      
         | 314 |  |  | // Whenever the frontend doesn't access the program memory,  backup the data
 | 
      
         | 315 |  |  |  
 | 
      
         | 316 |  |  | // Detect whenever the data should be backuped and restored
 | 
      
         | 317 |  |  | reg         fe_pmem_en_dly;
 | 
      
         | 318 |  |  | always @(posedge mclk or posedge puc_rst)
 | 
      
         | 319 |  |  |   if (puc_rst) fe_pmem_en_dly <=  1'b0;
 | 
      
         | 320 |  |  |   else         fe_pmem_en_dly <=  fe_pmem_en;
 | 
      
         | 321 |  |  |  
 | 
      
         | 322 |  |  | wire fe_pmem_save    = (~fe_pmem_en &  fe_pmem_en_dly) & ~cpu_halt_st;
 | 
      
         | 323 |  |  | wire fe_pmem_restore = ( fe_pmem_en & ~fe_pmem_en_dly) |  cpu_halt_st;
 | 
      
         | 324 |  |  |  
 | 
      
         | 325 |  |  | `ifdef CLOCK_GATING
 | 
      
         | 326 |  |  | wire mclk_bckup_gated;
 | 
      
         | 327 |  |  | omsp_clock_gate clock_gate_bckup (.gclk(mclk_bckup_gated),
 | 
      
         | 328 |  |  |                                   .clk (mclk), .enable(fe_pmem_save), .scan_enable(scan_enable));
 | 
      
         | 329 |  |  | `define MCLK_BCKUP           mclk_bckup_gated
 | 
      
         | 330 |  |  | `else
 | 
      
         | 331 |  |  | wire    UNUSED_scan_enable = scan_enable;
 | 
      
         | 332 |  |  | `define MCLK_BCKUP           mclk        // use macro to solve delta cycle issues with some mixed VHDL/Verilog simulators
 | 
      
         | 333 |  |  | `endif
 | 
      
         | 334 |  |  |  
 | 
      
         | 335 |  |  | reg  [15:0] pmem_dout_bckup;
 | 
      
         | 336 |  |  | always @(posedge `MCLK_BCKUP or posedge puc_rst)
 | 
      
         | 337 |  |  |   if (puc_rst)              pmem_dout_bckup     <=  16'h0000;
 | 
      
         | 338 |  |  | `ifdef CLOCK_GATING
 | 
      
         | 339 |  |  |   else                      pmem_dout_bckup     <=  pmem_dout;
 | 
      
         | 340 |  |  | `else
 | 
      
         | 341 |  |  |   else if (fe_pmem_save)    pmem_dout_bckup     <=  pmem_dout;
 | 
      
         | 342 |  |  | `endif
 | 
      
         | 343 |  |  |  
 | 
      
         | 344 |  |  | // Mux between the Program memory data and the backup
 | 
      
         | 345 |  |  | reg         pmem_dout_bckup_sel;
 | 
      
         | 346 |  |  | always @(posedge mclk or posedge puc_rst)
 | 
      
         | 347 |  |  |   if (puc_rst)              pmem_dout_bckup_sel <=  1'b0;
 | 
      
         | 348 |  |  |   else if (fe_pmem_save)    pmem_dout_bckup_sel <=  1'b1;
 | 
      
         | 349 |  |  |   else if (fe_pmem_restore) pmem_dout_bckup_sel <=  1'b0;
 | 
      
         | 350 |  |  |  
 | 
      
         | 351 |  |  | assign fe_mdb_in = pmem_dout_bckup_sel ? pmem_dout_bckup : pmem_dout;
 | 
      
         | 352 |  |  |  
 | 
      
         | 353 |  |  |  
 | 
      
         | 354 |  |  | //------------------------------------------
 | 
      
         | 355 |  |  | // Execution-Unit data Mux
 | 
      
         | 356 |  |  | //------------------------------------------
 | 
      
         | 357 |  |  |  
 | 
      
         | 358 |  |  | // Select between Peripherals, Program and Data memories
 | 
      
         | 359 |  |  | reg [1:0] eu_mdb_in_sel;
 | 
      
         | 360 |  |  | always @(posedge mclk or posedge puc_rst)
 | 
      
         | 361 |  |  |   if (puc_rst)  eu_mdb_in_sel  <= 2'b00;
 | 
      
         | 362 |  |  |   else          eu_mdb_in_sel  <= {eu_pmem_en, eu_per_en};
 | 
      
         | 363 |  |  |  
 | 
      
         | 364 |  |  | // Mux
 | 
      
         | 365 |  |  | assign          eu_mdb_in       = eu_mdb_in_sel[1] ? pmem_dout    :
 | 
      
         | 366 |  |  |                                   eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
 | 
      
         | 367 |  |  |  
 | 
      
         | 368 |  |  |  
 | 
      
         | 369 |  |  | //------------------------------------------
 | 
      
         | 370 |  |  | // External Master/Debug interface data Mux
 | 
      
         | 371 |  |  | //------------------------------------------
 | 
      
         | 372 |  |  |  
 | 
      
         | 373 |  |  | // Select between Peripherals, Program and Data memories
 | 
      
         | 374 |  |  | reg   [1:0] ext_mem_din_sel;
 | 
      
         | 375 |  |  | always @(posedge mclk or posedge puc_rst)
 | 
      
         | 376 |  |  |   if (puc_rst)  ext_mem_din_sel <= 2'b00;
 | 
      
         | 377 |  |  |   else          ext_mem_din_sel <= {ext_pmem_en, ext_per_en};
 | 
      
         | 378 |  |  |  
 | 
      
         | 379 |  |  | // Mux
 | 
      
         | 380 |  |  | assign          ext_mem_din      = ext_mem_din_sel[1] ? pmem_dout    :
 | 
      
         | 381 |  |  |                                    ext_mem_din_sel[0] ? per_dout_val : dmem_dout;
 | 
      
         | 382 |  |  |  
 | 
      
         | 383 |  |  |  
 | 
      
         | 384 |  |  | endmodule // omsp_mem_backbone
 | 
      
         | 385 |  |  |  
 | 
      
         | 386 |  |  | `ifdef OMSP_NO_INCLUDE
 | 
      
         | 387 |  |  | `else
 | 
      
         | 388 |  |  | `include "openMSP430_undefines.v"
 | 
      
         | 389 |  |  | `endif
 |