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 111

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

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2
// Copyright (C) 2001 Authors
3
//
4
// This source file may be used and distributed without restriction provided
5
// that this copyright statement is not removed from the file and that any
6
// derivative work contains the original copyright notice and the associated
7
// disclaimer.
8
//
9
// This source file is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation; either version 2.1 of the License, or
12
// (at your option) any later version.
13
//
14
// This source is distributed in the hope that it will be useful, but WITHOUT
15
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
// License for more details.
18
//
19
// You should have received a copy of the GNU Lesser General Public License
20
// along with this source; if not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
//
23
//----------------------------------------------------------------------------
24
//
25 34 olivier.gi
// *File Name: omsp_mem_backbone.v
26 2 olivier.gi
// 
27
// *Module Description:
28
//                       Memory interface backbone (decoder + arbiter)
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34 17 olivier.gi
// $Rev: 111 $
35
// $LastChangedBy: olivier.girard $
36
// $LastChangedDate: 2011-05-20 22:39:02 +0200 (Fri, 20 May 2011) $
37
//----------------------------------------------------------------------------
38 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
39
`else
40 23 olivier.gi
`include "openMSP430_defines.v"
41 103 olivier.gi
`endif
42 2 olivier.gi
 
43 34 olivier.gi
module  omsp_mem_backbone (
44 2 olivier.gi
 
45
// OUTPUTs
46
    dbg_mem_din,                    // Debug unit Memory data input
47 33 olivier.gi
    dmem_addr,                      // Data Memory address
48
    dmem_cen,                       // Data Memory chip enable (low active)
49
    dmem_din,                       // Data Memory data input
50
    dmem_wen,                       // Data Memory write enable (low active)
51 2 olivier.gi
    eu_mdb_in,                      // Execution Unit Memory data bus input
52
    fe_mdb_in,                      // Frontend Memory data bus input
53 33 olivier.gi
    fe_pmem_wait,                   // Frontend wait for Instruction fetch
54 2 olivier.gi
    per_addr,                       // Peripheral address
55
    per_din,                        // Peripheral data input
56 106 olivier.gi
    per_we,                         // Peripheral write enable (high active)
57 2 olivier.gi
    per_en,                         // Peripheral enable (high active)
58 33 olivier.gi
    pmem_addr,                      // Program Memory address
59
    pmem_cen,                       // Program Memory chip enable (low active)
60
    pmem_din,                       // Program Memory data input (optional)
61
    pmem_wen,                       // Program Memory write enable (low active) (optional)
62 2 olivier.gi
 
63
// INPUTs
64
    dbg_halt_st,                    // Halt/Run status from CPU
65
    dbg_mem_addr,                   // Debug address for rd/wr access
66
    dbg_mem_dout,                   // Debug unit data output
67
    dbg_mem_en,                     // Debug unit memory enable
68
    dbg_mem_wr,                     // Debug unit memory write
69 33 olivier.gi
    dmem_dout,                      // Data Memory data output
70 2 olivier.gi
    eu_mab,                         // Execution Unit Memory address bus
71
    eu_mb_en,                       // Execution Unit Memory bus enable
72
    eu_mb_wr,                       // Execution Unit Memory bus write transfer
73
    eu_mdb_out,                     // Execution Unit Memory data bus output
74
    fe_mab,                         // Frontend Memory address bus
75
    fe_mb_en,                       // Frontend Memory bus enable
76
    mclk,                           // Main system clock
77
    per_dout,                       // Peripheral data output
78 33 olivier.gi
    pmem_dout,                      // Program Memory data output
79 111 olivier.gi
    puc_rst                         // Main system reset
80 2 olivier.gi
);
81
 
82
// OUTPUTs
83
//=========
84 33 olivier.gi
output        [15:0] dbg_mem_din;   // Debug unit Memory data input
85
output [`DMEM_MSB:0] dmem_addr;     // Data Memory address
86
output               dmem_cen;      // Data Memory chip enable (low active)
87
output        [15:0] dmem_din;      // Data Memory data input
88
output         [1:0] dmem_wen;      // Data Memory write enable (low active)
89
output        [15:0] eu_mdb_in;     // Execution Unit Memory data bus input
90
output        [15:0] fe_mdb_in;     // Frontend Memory data bus input
91
output               fe_pmem_wait;  // Frontend wait for Instruction fetch
92 111 olivier.gi
output        [13:0] per_addr;      // Peripheral address
93 33 olivier.gi
output        [15:0] per_din;       // Peripheral data input
94 106 olivier.gi
output         [1:0] per_we;        // Peripheral write enable (high active)
95 33 olivier.gi
output               per_en;        // Peripheral enable (high active)
96
output [`PMEM_MSB:0] pmem_addr;     // Program Memory address
97
output               pmem_cen;      // Program Memory chip enable (low active)
98
output        [15:0] pmem_din;      // Program Memory data input (optional)
99
output         [1:0] pmem_wen;      // Program Memory write enable (low active) (optional)
100 2 olivier.gi
 
101
// INPUTs
102
//=========
103 33 olivier.gi
input                dbg_halt_st;   // Halt/Run status from CPU
104
input         [15:0] dbg_mem_addr;  // Debug address for rd/wr access
105
input         [15:0] dbg_mem_dout;  // Debug unit data output
106
input                dbg_mem_en;    // Debug unit memory enable
107
input          [1:0] dbg_mem_wr;    // Debug unit memory write
108
input         [15:0] dmem_dout;     // Data Memory data output
109
input         [14:0] eu_mab;        // Execution Unit Memory address bus
110
input                eu_mb_en;      // Execution Unit Memory bus enable
111
input          [1:0] eu_mb_wr;      // Execution Unit Memory bus write transfer
112
input         [15:0] eu_mdb_out;    // Execution Unit Memory data bus output
113
input         [14:0] fe_mab;        // Frontend Memory address bus
114
input                fe_mb_en;      // Frontend Memory bus enable
115
input                mclk;          // Main system clock
116
input         [15:0] per_dout;      // Peripheral data output
117
input         [15:0] pmem_dout;     // Program Memory data output
118 111 olivier.gi
input                puc_rst;       // Main system reset
119 2 olivier.gi
 
120
 
121
//=============================================================================
122
// 1)  DECODER
123
//=============================================================================
124
 
125
// RAM Interface
126
//------------------
127
 
128
// Execution unit access
129 33 olivier.gi
wire               eu_dmem_cen   = ~(eu_mb_en & (eu_mab>=(`DMEM_BASE>>1)) &
130
                                                (eu_mab<((`DMEM_BASE+`DMEM_SIZE)>>1)));
131 111 olivier.gi
wire        [15:0] eu_dmem_addr  = {1'b0, eu_mab}-(`DMEM_BASE>>1);
132 2 olivier.gi
 
133
// Debug interface access
134 33 olivier.gi
wire               dbg_dmem_cen  = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
135
                                                  (dbg_mem_addr[15:1]<((`DMEM_BASE+`DMEM_SIZE)>>1)));
136 111 olivier.gi
wire        [15:0] dbg_dmem_addr = {1'b0, dbg_mem_addr[15:1]}-(`DMEM_BASE>>1);
137 2 olivier.gi
 
138
 
139
// RAM Interface
140 33 olivier.gi
wire [`DMEM_MSB:0] dmem_addr     = ~dbg_dmem_cen ? dbg_dmem_addr[`DMEM_MSB:0] : eu_dmem_addr[`DMEM_MSB:0];
141
wire               dmem_cen      =  dbg_dmem_cen & eu_dmem_cen;
142
wire         [1:0] dmem_wen      = ~(dbg_mem_wr | eu_mb_wr);
143
wire        [15:0] dmem_din      = ~dbg_dmem_cen ? dbg_mem_dout : eu_mdb_out;
144 2 olivier.gi
 
145
 
146
// ROM Interface
147
//------------------
148 33 olivier.gi
parameter          PMEM_OFFSET   = (16'hFFFF-`PMEM_SIZE+1);
149 2 olivier.gi
 
150
// Execution unit access (only read access are accepted)
151 33 olivier.gi
wire               eu_pmem_cen   = ~(eu_mb_en & ~|eu_mb_wr & (eu_mab>=(PMEM_OFFSET>>1)));
152
wire        [15:0] eu_pmem_addr  = eu_mab-(PMEM_OFFSET>>1);
153 2 olivier.gi
 
154
// Front-end access
155 33 olivier.gi
wire               fe_pmem_cen   = ~(fe_mb_en & (fe_mab>=(PMEM_OFFSET>>1)));
156
wire        [15:0] fe_pmem_addr  = fe_mab-(PMEM_OFFSET>>1);
157 2 olivier.gi
 
158
// Debug interface access
159 33 olivier.gi
wire               dbg_pmem_cen  = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(PMEM_OFFSET>>1)));
160 111 olivier.gi
wire        [15:0] dbg_pmem_addr = {1'b0, dbg_mem_addr[15:1]}-(PMEM_OFFSET>>1);
161 2 olivier.gi
 
162
 
163
// ROM Interface (Execution unit has priority)
164 33 olivier.gi
wire [`PMEM_MSB:0] pmem_addr     = ~dbg_pmem_cen ? dbg_pmem_addr[`PMEM_MSB:0] :
165
                                   ~eu_pmem_cen  ? eu_pmem_addr[`PMEM_MSB:0]  : fe_pmem_addr[`PMEM_MSB:0];
166
wire               pmem_cen      =  fe_pmem_cen & eu_pmem_cen & dbg_pmem_cen;
167
wire         [1:0] pmem_wen      = ~dbg_mem_wr;
168
wire        [15:0] pmem_din      =  dbg_mem_dout;
169 2 olivier.gi
 
170 33 olivier.gi
wire               fe_pmem_wait  = (~fe_pmem_cen & ~eu_pmem_cen);
171 2 olivier.gi
 
172
 
173
// Peripherals
174
//--------------------
175 111 olivier.gi
wire              dbg_per_en   =  dbg_mem_en & (dbg_mem_addr[15:`PER_AWIDTH+1]=={15-`PER_AWIDTH{1'b0}});
176
wire              eu_per_en    =  eu_mb_en   & (eu_mab[14:`PER_AWIDTH]        =={15-`PER_AWIDTH{1'b0}});
177 2 olivier.gi
 
178 111 olivier.gi
wire       [15:0] per_din      =  dbg_mem_en ? dbg_mem_dout               : eu_mdb_out;
179
wire        [1:0] per_we       =  dbg_mem_en ? dbg_mem_wr                 : eu_mb_wr;
180
wire              per_en       =  dbg_mem_en ? dbg_per_en                 : eu_per_en;
181
wire [`PER_MSB:0] per_addr_mux =  dbg_mem_en ? dbg_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
182
wire       [14:0] per_addr_ful =  {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
183
wire       [13:0] per_addr     =   per_addr_ful[13:0];
184 2 olivier.gi
 
185
reg   [15:0] per_dout_val;
186 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
187
  if (puc_rst)  per_dout_val <= 16'h0000;
188 2 olivier.gi
  else          per_dout_val <= per_dout;
189
 
190
 
191
// Frontend data Mux
192
//---------------------------------
193
// Whenever the frontend doesn't access the ROM,  backup the data
194
 
195
// Detect whenever the data should be backuped and restored
196 33 olivier.gi
reg         fe_pmem_cen_dly;
197 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
198
  if (puc_rst) fe_pmem_cen_dly <=  1'b0;
199 33 olivier.gi
  else         fe_pmem_cen_dly <=  fe_pmem_cen;
200 2 olivier.gi
 
201 33 olivier.gi
wire fe_pmem_save    = ( fe_pmem_cen & ~fe_pmem_cen_dly) & ~dbg_halt_st;
202
wire fe_pmem_restore = (~fe_pmem_cen &  fe_pmem_cen_dly) |  dbg_halt_st;
203 2 olivier.gi
 
204 33 olivier.gi
reg  [15:0] pmem_dout_bckup;
205 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
206
  if (puc_rst)           pmem_dout_bckup     <=  16'h0000;
207 33 olivier.gi
  else if (fe_pmem_save) pmem_dout_bckup     <=  pmem_dout;
208 2 olivier.gi
 
209
// Mux between the ROM data and the backup
210 33 olivier.gi
reg         pmem_dout_bckup_sel;
211 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
212
  if (puc_rst)              pmem_dout_bckup_sel <=  1'b0;
213 33 olivier.gi
  else if (fe_pmem_save)    pmem_dout_bckup_sel <=  1'b1;
214
  else if (fe_pmem_restore) pmem_dout_bckup_sel <=  1'b0;
215 2 olivier.gi
 
216 33 olivier.gi
assign fe_mdb_in = pmem_dout_bckup_sel ? pmem_dout_bckup : pmem_dout;
217 2 olivier.gi
 
218
 
219
// Execution-Unit data Mux
220
//---------------------------------
221
 
222
// Select between peripherals, RAM and ROM
223
reg [1:0] eu_mdb_in_sel;
224 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
225
  if (puc_rst)  eu_mdb_in_sel <= 2'b00;
226
  else          eu_mdb_in_sel <= {~eu_pmem_cen, per_en};
227 2 olivier.gi
 
228
// Mux
229 33 olivier.gi
assign      eu_mdb_in      = eu_mdb_in_sel[1] ? pmem_dout    :
230
                             eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
231 2 olivier.gi
 
232
// Debug interface  data Mux
233
//---------------------------------
234
 
235
// Select between peripherals, RAM and ROM
236 106 olivier.gi
`ifdef DBG_EN
237
reg   [1:0] dbg_mem_din_sel;
238 111 olivier.gi
always @(posedge mclk or posedge puc_rst)
239
  if (puc_rst)  dbg_mem_din_sel <= 2'b00;
240
  else          dbg_mem_din_sel <= {~dbg_pmem_cen, dbg_per_en};
241 2 olivier.gi
 
242 106 olivier.gi
`else
243
wire  [1:0] dbg_mem_din_sel  = 2'b00;
244
`endif
245
 
246 2 olivier.gi
// Mux
247 33 olivier.gi
assign      dbg_mem_din  = dbg_mem_din_sel[1] ? pmem_dout    :
248
                           dbg_mem_din_sel[0] ? per_dout_val : dmem_dout;
249 2 olivier.gi
 
250
 
251 34 olivier.gi
endmodule // omsp_mem_backbone
252 2 olivier.gi
 
253 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
254
`else
255 33 olivier.gi
`include "openMSP430_undefines.v"
256 103 olivier.gi
`endif

powered by: WebSVN 2.1.0

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