OpenCores
URL https://opencores.org/ocsvn/openmsp430/openmsp430/trunk

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [omsp_mem_backbone.v] - Blame information for rev 134

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2 117 olivier.gi
// Copyright (C) 2009 , Olivier Girard
3 2 olivier.gi
//
4 117 olivier.gi
// 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 2 olivier.gi
//
16 117 olivier.gi
// 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 2 olivier.gi
//
28
//----------------------------------------------------------------------------
29
//
30 34 olivier.gi
// *File Name: omsp_mem_backbone.v
31 2 olivier.gi
// 
32
// *Module Description:
33
//                       Memory interface backbone (decoder + arbiter)
34
//
35
// *Author(s):
36
//              - Olivier Girard,    olgirard@gmail.com
37
//
38
//----------------------------------------------------------------------------
39 17 olivier.gi
// $Rev: 134 $
40
// $LastChangedBy: olivier.girard $
41
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
42
//----------------------------------------------------------------------------
43 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
44
`else
45 23 olivier.gi
`include "openMSP430_defines.v"
46 103 olivier.gi
`endif
47 2 olivier.gi
 
48 34 olivier.gi
module  omsp_mem_backbone (
49 2 olivier.gi
 
50
// OUTPUTs
51
    dbg_mem_din,                    // Debug unit Memory data input
52 33 olivier.gi
    dmem_addr,                      // Data Memory address
53
    dmem_cen,                       // Data Memory chip enable (low active)
54
    dmem_din,                       // Data Memory data input
55
    dmem_wen,                       // Data Memory write enable (low active)
56 2 olivier.gi
    eu_mdb_in,                      // Execution Unit Memory data bus input
57
    fe_mdb_in,                      // Frontend Memory data bus input
58 33 olivier.gi
    fe_pmem_wait,                   // Frontend wait for Instruction fetch
59 2 olivier.gi
    per_addr,                       // Peripheral address
60
    per_din,                        // Peripheral data input
61 106 olivier.gi
    per_we,                         // Peripheral write enable (high active)
62 2 olivier.gi
    per_en,                         // Peripheral enable (high active)
63 33 olivier.gi
    pmem_addr,                      // Program Memory address
64
    pmem_cen,                       // Program Memory chip enable (low active)
65
    pmem_din,                       // Program Memory data input (optional)
66
    pmem_wen,                       // Program Memory write enable (low active) (optional)
67 2 olivier.gi
 
68
// INPUTs
69
    dbg_halt_st,                    // Halt/Run status from CPU
70
    dbg_mem_addr,                   // Debug address for rd/wr access
71
    dbg_mem_dout,                   // Debug unit data output
72
    dbg_mem_en,                     // Debug unit memory enable
73
    dbg_mem_wr,                     // Debug unit memory write
74 33 olivier.gi
    dmem_dout,                      // Data Memory data output
75 2 olivier.gi
    eu_mab,                         // Execution Unit Memory address bus
76
    eu_mb_en,                       // Execution Unit Memory bus enable
77
    eu_mb_wr,                       // Execution Unit Memory bus write transfer
78
    eu_mdb_out,                     // Execution Unit Memory data bus output
79
    fe_mab,                         // Frontend Memory address bus
80
    fe_mb_en,                       // Frontend Memory bus enable
81
    mclk,                           // Main system clock
82
    per_dout,                       // Peripheral data output
83 33 olivier.gi
    pmem_dout,                      // Program Memory data output
84 134 olivier.gi
    puc_rst,                        // Main system reset
85
    scan_enable                     // Scan enable (active during scan shifting)
86 2 olivier.gi
);
87
 
88
// OUTPUTs
89
//=========
90 33 olivier.gi
output        [15:0] dbg_mem_din;   // Debug unit Memory data input
91
output [`DMEM_MSB:0] dmem_addr;     // Data Memory address
92
output               dmem_cen;      // Data Memory chip enable (low active)
93
output        [15:0] dmem_din;      // Data Memory data input
94
output         [1:0] dmem_wen;      // Data Memory write enable (low active)
95
output        [15:0] eu_mdb_in;     // Execution Unit Memory data bus input
96
output        [15:0] fe_mdb_in;     // Frontend Memory data bus input
97
output               fe_pmem_wait;  // Frontend wait for Instruction fetch
98 111 olivier.gi
output        [13:0] per_addr;      // Peripheral address
99 33 olivier.gi
output        [15:0] per_din;       // Peripheral data input
100 106 olivier.gi
output         [1:0] per_we;        // Peripheral write enable (high active)
101 33 olivier.gi
output               per_en;        // Peripheral enable (high active)
102
output [`PMEM_MSB:0] pmem_addr;     // Program Memory address
103
output               pmem_cen;      // Program Memory chip enable (low active)
104
output        [15:0] pmem_din;      // Program Memory data input (optional)
105
output         [1:0] pmem_wen;      // Program Memory write enable (low active) (optional)
106 2 olivier.gi
 
107
// INPUTs
108
//=========
109 33 olivier.gi
input                dbg_halt_st;   // Halt/Run status from CPU
110
input         [15:0] dbg_mem_addr;  // Debug address for rd/wr access
111
input         [15:0] dbg_mem_dout;  // Debug unit data output
112
input                dbg_mem_en;    // Debug unit memory enable
113
input          [1:0] dbg_mem_wr;    // Debug unit memory write
114
input         [15:0] dmem_dout;     // Data Memory data output
115
input         [14:0] eu_mab;        // Execution Unit Memory address bus
116
input                eu_mb_en;      // Execution Unit Memory bus enable
117
input          [1:0] eu_mb_wr;      // Execution Unit Memory bus write transfer
118
input         [15:0] eu_mdb_out;    // Execution Unit Memory data bus output
119
input         [14:0] fe_mab;        // Frontend Memory address bus
120
input                fe_mb_en;      // Frontend Memory bus enable
121
input                mclk;          // Main system clock
122
input         [15:0] per_dout;      // Peripheral data output
123
input         [15:0] pmem_dout;     // Program Memory data output
124 111 olivier.gi
input                puc_rst;       // Main system reset
125 134 olivier.gi
input                scan_enable;   // Scan enable (active during scan shifting)
126 2 olivier.gi
 
127
 
128
//=============================================================================
129
// 1)  DECODER
130
//=============================================================================
131
 
132
// RAM Interface
133
//------------------
134
 
135
// Execution unit access
136 33 olivier.gi
wire               eu_dmem_cen   = ~(eu_mb_en & (eu_mab>=(`DMEM_BASE>>1)) &
137
                                                (eu_mab<((`DMEM_BASE+`DMEM_SIZE)>>1)));
138 111 olivier.gi
wire        [15:0] eu_dmem_addr  = {1'b0, eu_mab}-(`DMEM_BASE>>1);
139 2 olivier.gi
 
140
// Debug interface access
141 33 olivier.gi
wire               dbg_dmem_cen  = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
142
                                                  (dbg_mem_addr[15:1]<((`DMEM_BASE+`DMEM_SIZE)>>1)));
143 111 olivier.gi
wire        [15:0] dbg_dmem_addr = {1'b0, dbg_mem_addr[15:1]}-(`DMEM_BASE>>1);
144 2 olivier.gi
 
145
 
146
// RAM Interface
147 33 olivier.gi
wire [`DMEM_MSB:0] dmem_addr     = ~dbg_dmem_cen ? dbg_dmem_addr[`DMEM_MSB:0] : eu_dmem_addr[`DMEM_MSB:0];
148
wire               dmem_cen      =  dbg_dmem_cen & eu_dmem_cen;
149
wire         [1:0] dmem_wen      = ~(dbg_mem_wr | eu_mb_wr);
150
wire        [15:0] dmem_din      = ~dbg_dmem_cen ? dbg_mem_dout : eu_mdb_out;
151 2 olivier.gi
 
152
 
153
// ROM Interface
154
//------------------
155 33 olivier.gi
parameter          PMEM_OFFSET   = (16'hFFFF-`PMEM_SIZE+1);
156 2 olivier.gi
 
157
// Execution unit access (only read access are accepted)
158 33 olivier.gi
wire               eu_pmem_cen   = ~(eu_mb_en & ~|eu_mb_wr & (eu_mab>=(PMEM_OFFSET>>1)));
159
wire        [15:0] eu_pmem_addr  = eu_mab-(PMEM_OFFSET>>1);
160 2 olivier.gi
 
161
// Front-end access
162 33 olivier.gi
wire               fe_pmem_cen   = ~(fe_mb_en & (fe_mab>=(PMEM_OFFSET>>1)));
163
wire        [15:0] fe_pmem_addr  = fe_mab-(PMEM_OFFSET>>1);
164 2 olivier.gi
 
165
// Debug interface access
166 33 olivier.gi
wire               dbg_pmem_cen  = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(PMEM_OFFSET>>1)));
167 111 olivier.gi
wire        [15:0] dbg_pmem_addr = {1'b0, dbg_mem_addr[15:1]}-(PMEM_OFFSET>>1);
168 2 olivier.gi
 
169
 
170
// ROM Interface (Execution unit has priority)
171 33 olivier.gi
wire [`PMEM_MSB:0] pmem_addr     = ~dbg_pmem_cen ? dbg_pmem_addr[`PMEM_MSB:0] :
172
                                   ~eu_pmem_cen  ? eu_pmem_addr[`PMEM_MSB:0]  : fe_pmem_addr[`PMEM_MSB:0];
173
wire               pmem_cen      =  fe_pmem_cen & eu_pmem_cen & dbg_pmem_cen;
174
wire         [1:0] pmem_wen      = ~dbg_mem_wr;
175
wire        [15:0] pmem_din      =  dbg_mem_dout;
176 2 olivier.gi
 
177 33 olivier.gi
wire               fe_pmem_wait  = (~fe_pmem_cen & ~eu_pmem_cen);
178 2 olivier.gi
 
179
 
180
// Peripherals
181
//--------------------
182 111 olivier.gi
wire              dbg_per_en   =  dbg_mem_en & (dbg_mem_addr[15:`PER_AWIDTH+1]=={15-`PER_AWIDTH{1'b0}});
183
wire              eu_per_en    =  eu_mb_en   & (eu_mab[14:`PER_AWIDTH]        =={15-`PER_AWIDTH{1'b0}});
184 2 olivier.gi
 
185 111 olivier.gi
wire       [15:0] per_din      =  dbg_mem_en ? dbg_mem_dout               : eu_mdb_out;
186
wire        [1:0] per_we       =  dbg_mem_en ? dbg_mem_wr                 : eu_mb_wr;
187
wire              per_en       =  dbg_mem_en ? dbg_per_en                 : eu_per_en;
188
wire [`PER_MSB:0] per_addr_mux =  dbg_mem_en ? dbg_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
189
wire       [14:0] per_addr_ful =  {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
190
wire       [13:0] per_addr     =   per_addr_ful[13:0];
191 2 olivier.gi
 
192
reg   [15:0] per_dout_val;
193 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
194
  if (puc_rst)  per_dout_val <= 16'h0000;
195 2 olivier.gi
  else          per_dout_val <= per_dout;
196
 
197
 
198
// Frontend data Mux
199
//---------------------------------
200
// Whenever the frontend doesn't access the ROM,  backup the data
201
 
202
// Detect whenever the data should be backuped and restored
203 33 olivier.gi
reg         fe_pmem_cen_dly;
204 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
205
  if (puc_rst) fe_pmem_cen_dly <=  1'b0;
206 33 olivier.gi
  else         fe_pmem_cen_dly <=  fe_pmem_cen;
207 2 olivier.gi
 
208 33 olivier.gi
wire fe_pmem_save    = ( fe_pmem_cen & ~fe_pmem_cen_dly) & ~dbg_halt_st;
209
wire fe_pmem_restore = (~fe_pmem_cen &  fe_pmem_cen_dly) |  dbg_halt_st;
210 134 olivier.gi
 
211
`ifdef CLOCK_GATING
212
wire mclk_bckup;
213
omsp_clock_gate clock_gate_bckup (.gclk(mclk_bckup),
214
                                  .clk (mclk), .enable(fe_pmem_save), .scan_enable(scan_enable));
215
`else
216
wire mclk_bckup = mclk;
217
`endif
218 2 olivier.gi
 
219 33 olivier.gi
reg  [15:0] pmem_dout_bckup;
220 134 olivier.gi
always @(posedge mclk_bckup or posedge puc_rst)
221 111 olivier.gi
  if (puc_rst)           pmem_dout_bckup     <=  16'h0000;
222 134 olivier.gi
`ifdef CLOCK_GATING
223
  else                   pmem_dout_bckup     <=  pmem_dout;
224
`else
225 33 olivier.gi
  else if (fe_pmem_save) pmem_dout_bckup     <=  pmem_dout;
226 134 olivier.gi
`endif
227 2 olivier.gi
 
228
// Mux between the ROM data and the backup
229 33 olivier.gi
reg         pmem_dout_bckup_sel;
230 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
231
  if (puc_rst)              pmem_dout_bckup_sel <=  1'b0;
232 33 olivier.gi
  else if (fe_pmem_save)    pmem_dout_bckup_sel <=  1'b1;
233
  else if (fe_pmem_restore) pmem_dout_bckup_sel <=  1'b0;
234 2 olivier.gi
 
235 33 olivier.gi
assign fe_mdb_in = pmem_dout_bckup_sel ? pmem_dout_bckup : pmem_dout;
236 2 olivier.gi
 
237
 
238
// Execution-Unit data Mux
239
//---------------------------------
240
 
241
// Select between peripherals, RAM and ROM
242
reg [1:0] eu_mdb_in_sel;
243 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
244
  if (puc_rst)  eu_mdb_in_sel <= 2'b00;
245
  else          eu_mdb_in_sel <= {~eu_pmem_cen, per_en};
246 2 olivier.gi
 
247
// Mux
248 33 olivier.gi
assign      eu_mdb_in      = eu_mdb_in_sel[1] ? pmem_dout    :
249
                             eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
250 2 olivier.gi
 
251
// Debug interface  data Mux
252
//---------------------------------
253
 
254
// Select between peripherals, RAM and ROM
255 106 olivier.gi
`ifdef DBG_EN
256
reg   [1:0] dbg_mem_din_sel;
257 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
258
  if (puc_rst)  dbg_mem_din_sel <= 2'b00;
259
  else          dbg_mem_din_sel <= {~dbg_pmem_cen, dbg_per_en};
260 2 olivier.gi
 
261 106 olivier.gi
`else
262
wire  [1:0] dbg_mem_din_sel  = 2'b00;
263
`endif
264
 
265 2 olivier.gi
// Mux
266 33 olivier.gi
assign      dbg_mem_din  = dbg_mem_din_sel[1] ? pmem_dout    :
267
                           dbg_mem_din_sel[0] ? per_dout_val : dmem_dout;
268 2 olivier.gi
 
269
 
270 34 olivier.gi
endmodule // omsp_mem_backbone
271 2 olivier.gi
 
272 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
273
`else
274 33 olivier.gi
`include "openMSP430_undefines.v"
275 103 olivier.gi
`endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.