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