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

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [tools/] [src/] [wigen/] [generator.cpp] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 ring0_mipt
/*
2
 * Copyright (c) 2016 by Alex I. Kuznetsov.
3
 *
4
 * Part of the LXP32 CPU IP core.
5
 *
6
 * This module implements members of the Generator class.
7
 */
8
 
9
#ifdef _MSC_VER
10
        #define _CRT_SECURE_NO_WARNINGS
11
#endif
12
 
13
#include "generator.h"
14
 
15
#include <iostream>
16
#include <fstream>
17
#include <sstream>
18
#include <stdexcept>
19
#include <cctype>
20
#include <ctime>
21
 
22
Generator::Generator():
23
        _masters(1),
24
        _slaves(1),
25
        _addrWidth(32),
26
        _portSize(32),
27
        _portGranularity(32),
28
        _entityName("intercon"),
29
        _pipelinedArbiter(false),
30
        _registeredFeedback(false),
31
        _unsafeDecoder(false) {}
32
 
33
void Generator::setMasters(int i) {
34
        if(i<1) throw std::runtime_error("Invalid number of masters");
35
        _masters=i;
36
}
37
 
38
void Generator::setSlaves(int i) {
39
        if(i<1) throw std::runtime_error("Invalid number of slaves");
40
        _slaves=i;
41
}
42
 
43
void Generator::setAddrWidth(int i) {
44
        if(i<1) throw std::runtime_error("Invalid address width");
45
        _addrWidth=i;
46
}
47
 
48
void Generator::setSlaveAddrWidth(int i) {
49
        if(i<1) throw std::runtime_error("Invalid slave address width");
50
        _slaveAddrWidth=i;
51
}
52
 
53
void Generator::setPortSize(int i) {
54
        if(i!=8&&i!=16&&i!=32&&i!=64)
55
                throw std::runtime_error("Invalid port size: 8, 16, 32 or 64 expected");
56
        _portSize=i;
57
}
58
 
59
void Generator::setPortGranularity(int i) {
60
        if(i!=8&&i!=16&&i!=32&&i!=64)
61
                throw std::runtime_error("Invalid port granularity: 8, 16, 32 or 64 expected");
62
        _portGranularity=i;
63
}
64
 
65
void Generator::setEntityName(const std::string &str) try {
66
        if(str.empty()) throw std::exception();
67
// First character must be a letter
68
        if(!std::isalpha(str[0])) throw std::exception();
69
// Subsequent characters can be letters, digits or underscores
70
        for(std::size_t i=1;i<str.size();i++)
71
                if(!std::isalnum(str[i])&&str[i]!='_') throw std::exception();
72
 
73
        _entityName=str;
74
}
75
catch(std::exception &) {
76
        throw std::runtime_error("Invalid entity name");
77
}
78
 
79
void Generator::setPipelinedArbiter(bool b) {
80
        _pipelinedArbiter=b;
81
}
82
 
83
void Generator::setRegisteredFeedback(bool b) {
84
        _registeredFeedback=b;
85
}
86
 
87
void Generator::setUnsafeDecoder(bool b) {
88
        _unsafeDecoder=b;
89
}
90
 
91
int Generator::masters() const {
92
        return _masters;
93
}
94
 
95
int Generator::slaves() const {
96
        return _slaves;
97
}
98
 
99
int Generator::addrWidth() const {
100
        return _addrWidth;
101
}
102
 
103
int Generator::slaveAddrWidth() const {
104
        return _slaveAddrWidth;
105
}
106
 
107
int Generator::portSize() const {
108
        return _portSize;
109
}
110
 
111
int Generator::portGranularity() const {
112
        return _portGranularity;
113
}
114
 
115
std::string Generator::entityName() const {
116
        return _entityName;
117
}
118
 
119
bool Generator::pipelinedArbiter() const {
120
        return _pipelinedArbiter;
121
}
122
 
123
bool Generator::registeredFeedback() const {
124
        return _registeredFeedback;
125
}
126
 
127
bool Generator::unsafeDecoder() const {
128
        return _unsafeDecoder;
129
}
130
 
131
void Generator::generate(const std::string &filename) {
132
        prepare();
133
 
134
        std::ofstream out(filename,std::ios_base::out);
135
        if(!out) throw std::runtime_error("Cannot open \""+filename+"\"");
136
 
137
        writeBanner(out);
138
        writePreamble(out);
139
        writeEntity(out);
140
        writeArchitecture(out);
141
}
142
 
143
/*
144
 * Private members
145
 */
146
 
147
void Generator::prepare() {
148
        _fallbackSlave=false;
149
        if(slaves()<(1<<(addrWidth()-slaveAddrWidth()))&&!unsafeDecoder())
150
                _fallbackSlave=true;
151
 
152
        _mastersRange.assign(masters()-1,0);
153
        if(_fallbackSlave) _slavesRange.assign(slaves(),0);
154
        else _slavesRange.assign(slaves()-1,0);
155
 
156
        int q=portSize()/portGranularity();
157
 
158
        switch(q) {
159
        case 1:
160
                _addrRange.assign(addrWidth()-1,0);
161
                break;
162
        case 2:
163
                if(addrWidth()<=1) throw std::runtime_error("Invalid master address width");
164
                _addrRange.assign(addrWidth()-1,1);
165
                _selRange.assign(1,0);
166
                break;
167
        case 4:
168
                if(addrWidth()<=2) throw std::runtime_error("Invalid master address width");
169
                _addrRange.assign(addrWidth()-1,2);
170
                _selRange.assign(3,0);
171
                break;
172
        case 8:
173
                if(addrWidth()<=3) throw std::runtime_error("Invalid master address width");
174
                _addrRange.assign(addrWidth()-1,3);
175
                _selRange.assign(7,0);
176
                break;
177
        default:
178
                throw std::runtime_error("Invalid port size/granularity combination");
179
        }
180
 
181
        if(slaveAddrWidth()>addrWidth()) throw std::runtime_error("Invalid slave address width");
182
        if(slaves()>(1<<(addrWidth()-slaveAddrWidth()))) throw std::runtime_error("Invalid slave address width");
183
        if(slaveAddrWidth()<=_addrRange.low()) throw std::runtime_error("Invalid slave address width");
184
 
185
        _slaveAddrRange.assign(slaveAddrWidth()-1,_addrRange.low());
186
 
187
        if(slaves()>1) {
188
                _slaveDecoderRange.assign(_addrRange.high(),slaveAddrWidth());
189
                if(unsafeDecoder()) {
190
                        int requiredSize=0;
191
                        while((1<<requiredSize)<slaves()) requiredSize++;
192
                        _slaveDecoderRange.assign(_slaveDecoderRange.low()+requiredSize-1,
193
                                _slaveDecoderRange.low());
194
                }
195
        }
196
        _dataRange.assign(portSize()-1,0);
197
}
198
 
199
void Generator::writeBanner(std::ostream &os) {
200
        auto t=std::time(NULL);
201
        char szTime[256];
202
        auto r=std::strftime(szTime,256,"%c",std::localtime(&t));
203
        if(r==0) szTime[0]='\0';
204
 
205
        os<<"---------------------------------------------------------------------"<<std::endl;
206
        os<<"-- Simple WISHBONE interconnect"<<std::endl;
207
        os<<"--"<<std::endl;
208
        os<<"-- Generated by wigen at "<<szTime<<std::endl;
209
        os<<"--"<<std::endl;
210
        os<<"-- Configuration:"<<std::endl;
211
        os<<"--     Number of masters:     "<<masters()<<std::endl;
212
        os<<"--     Number of slaves:      "<<slaves()<<std::endl;
213
        os<<"--     Master address width:  "<<addrWidth()<<std::endl;
214
        os<<"--     Slave address width:   "<<slaveAddrWidth()<<std::endl;
215
        os<<"--     Port size:             "<<portSize()<<std::endl;
216
        os<<"--     Port granularity:      "<<portGranularity()<<std::endl;
217
        os<<"--     Entity name:           "<<entityName()<<std::endl;
218
        os<<"--     Pipelined arbiter:     "<<(pipelinedArbiter()?"yes":"no")<<std::endl;
219
        os<<"--     Registered feedback:   "<<(registeredFeedback()?"yes":"no")<<std::endl;
220
        os<<"--     Unsafe slave decoder:  "<<(unsafeDecoder()?"yes":"no")<<std::endl;
221
        os<<"--"<<std::endl;
222
        os<<"-- Command line:"<<std::endl;
223
        os<<"--     wigen -e "<<entityName();
224
        if(pipelinedArbiter()) os<<" -p";
225
        if(registeredFeedback()) os<<" -r";
226
        if(unsafeDecoder()) os<<" -u";
227
        os<<" "<<masters()<<" "<<slaves()<<" "<<addrWidth()<<" "<<slaveAddrWidth();
228
        os<<" "<<portSize()<<" "<<portGranularity()<<std::endl;
229
        os<<"---------------------------------------------------------------------"<<std::endl;
230
        os<<std::endl;
231
}
232
 
233
void Generator::writePreamble(std::ostream &os) {
234
        os<<"library ieee;"<<std::endl;
235
        os<<"use ieee.std_logic_1164.all;"<<std::endl;
236
        os<<std::endl;
237
}
238
 
239
void Generator::writeEntity(std::ostream &os) {
240
        os<<"entity "<<entityName()<<" is"<<std::endl;
241
        os<<"\tport("<<std::endl;
242
        os<<"\t\tclk_i: in std_logic;"<<std::endl;
243
        os<<"\t\trst_i: in std_logic;"<<std::endl;
244
        os<<std::endl;
245
 
246
        for(int i=0;i<masters();i++) {
247
                os<<"\t\ts"<<i<<"_cyc_i: in std_logic;"<<std::endl;
248
                os<<"\t\ts"<<i<<"_stb_i: in std_logic;"<<std::endl;
249
                os<<"\t\ts"<<i<<"_we_i: in std_logic;"<<std::endl;
250
                if(_selRange.valid())
251
                        os<<"\t\ts"<<i<<"_sel_i: in std_logic_vector("<<_selRange.toString()<<");"<<std::endl;
252
                if(registeredFeedback()) {
253
                        os<<"\t\ts"<<i<<"_cti_i: in std_logic_vector(2 downto 0);"<<std::endl;
254
                        os<<"\t\ts"<<i<<"_bte_i: in std_logic_vector(1 downto 0);"<<std::endl;
255
                }
256
                os<<"\t\ts"<<i<<"_ack_o: out std_logic;"<<std::endl;
257
                os<<"\t\ts"<<i<<"_adr_i: in std_logic_vector("<<_addrRange.toString()<<");"<<std::endl;
258
                os<<"\t\ts"<<i<<"_dat_i: in std_logic_vector("<<_dataRange.toString()<<");"<<std::endl;
259
                os<<"\t\ts"<<i<<"_dat_o: out std_logic_vector("<<_dataRange.toString()<<");"<<std::endl;
260
                os<<std::endl;
261
        }
262
 
263
        for(int i=0;i<slaves();i++) {
264
                os<<"\t\tm"<<i<<"_cyc_o: out std_logic;"<<std::endl;
265
                os<<"\t\tm"<<i<<"_stb_o: out std_logic;"<<std::endl;
266
                os<<"\t\tm"<<i<<"_we_o: out std_logic;"<<std::endl;
267
                if(_selRange.valid())
268
                        os<<"\t\tm"<<i<<"_sel_o: out std_logic_vector("<<_selRange.toString()<<");"<<std::endl;
269
                if(registeredFeedback()) {
270
                        os<<"\t\tm"<<i<<"_cti_o: out std_logic_vector(2 downto 0);"<<std::endl;
271
                        os<<"\t\tm"<<i<<"_bte_o: out std_logic_vector(1 downto 0);"<<std::endl;
272
                }
273
                os<<"\t\tm"<<i<<"_ack_i: in std_logic;"<<std::endl;
274
                os<<"\t\tm"<<i<<"_adr_o: out std_logic_vector("<<_slaveAddrRange.toString()<<");"<<std::endl;
275
                os<<"\t\tm"<<i<<"_dat_o: out std_logic_vector("<<_dataRange.toString()<<");"<<std::endl;
276
                os<<"\t\tm"<<i<<"_dat_i: in std_logic_vector("<<_dataRange.toString()<<")";
277
                if(i!=slaves()-1) os<<";"<<std::endl<<std::endl;
278
                else os<<std::endl;
279
        }
280
 
281
        os<<"\t);"<<std::endl;
282
        os<<"end entity;"<<std::endl;
283
        os<<std::endl;
284
}
285
 
286
void Generator::writeArchitecture(std::ostream &os) {
287
        os<<"architecture rtl of "<<entityName()<<" is"<<std::endl;
288
        os<<std::endl;
289
 
290
        if(masters()>1) {
291
                os<<"signal request: std_logic_vector("<<
292
                        _mastersRange.toString()<<");"<<std::endl;
293
                os<<"signal grant_next: std_logic_vector("<<
294
                        _mastersRange.toString()<<");"<<std::endl;
295
                os<<"signal grant: std_logic_vector("<<
296
                        _mastersRange.toString()<<");"<<std::endl;
297
 
298
                if(!pipelinedArbiter()) {
299
                        os<<"signal grant_reg: std_logic_vector("<<
300
                                _mastersRange.toString()<<"):=(others=>\'0\');"<<std::endl;
301
                }
302
 
303
                os<<std::endl;
304
        }
305
 
306
        if(slaves()>1) {
307
                os<<"signal select_slave: std_logic_vector("<<
308
                        _slavesRange.toString()<<");"<<std::endl;
309
                os<<std::endl;
310
        }
311
 
312
        os<<"signal cyc_mux: std_logic;"<<std::endl;
313
        os<<"signal stb_mux: std_logic;"<<std::endl;
314
        os<<"signal we_mux: std_logic;"<<std::endl;
315
        if(_selRange.valid())
316
                os<<"signal sel_mux: std_logic_vector("<<_selRange.toString()<<");"<<std::endl;
317
        if(registeredFeedback()) {
318
                os<<"signal cti_mux: std_logic_vector(2 downto 0);"<<std::endl;
319
                os<<"signal bte_mux: std_logic_vector(1 downto 0);"<<std::endl;
320
        }
321
        os<<"signal adr_mux: std_logic_vector("<<_addrRange.toString()<<");"<<std::endl;
322
        os<<"signal wdata_mux: std_logic_vector("<<_dataRange.toString()<<");"<<std::endl;
323
        os<<std::endl;
324
 
325
        os<<"signal ack_mux: std_logic;"<<std::endl;
326
        os<<"signal rdata_mux: std_logic_vector("<<_dataRange.toString()<<");"<<std::endl;
327
        os<<std::endl;
328
 
329
        os<<"begin"<<std::endl;
330
        os<<std::endl;
331
 
332
        if(masters()>1) writeArbiter(os);
333
        writeMasterMux(os);
334
        writeMasterDemux(os);
335
        writeSlaveMux(os);
336
        writeSlaveDemux(os);
337
 
338
        os<<"end architecture;"<<std::endl;
339
}
340
 
341
void Generator::writeArbiter(std::ostream &os) {
342
        os<<"-- ARBITER"<<std::endl;
343
        os<<"-- Selects the active master. Masters with lower port numbers"<<std::endl;
344
        os<<"-- have higher priority. Ongoing cycles are not interrupted."<<std::endl;
345
        os<<std::endl;
346
 
347
        os<<"request<=";
348
        for(int i=_mastersRange.high();i>=_mastersRange.low();i--) {
349
                os<<"s"<<i<<"_cyc_i";
350
                if(i>0) os<<'&';
351
        }
352
        os<<';'<<std::endl<<std::endl;
353
 
354
        os<<"grant_next<=";
355
        for(int i=0;i<masters();i++) {
356
                if(i>0) os<<'\t';
357
                os<<decodedLiteral(i,masters());
358
                os<<" when request("<<i<<")=\'1\' else"<<std::endl;
359
        }
360
        os<<"\t(others=>\'0\');"<<std::endl;
361
        os<<std::endl;
362
 
363
        if(!pipelinedArbiter()) {
364
                os<<"grant<=grant_reg when (request and grant_reg)/=";
365
                os<<binaryLiteral(0,masters());
366
                os<<" else grant_next;"<<std::endl;
367
                os<<std::endl;
368
 
369
                os<<"process (clk_i) is"<<std::endl;
370
                os<<"begin"<<std::endl;
371
                os<<"\tif rising_edge(clk_i) then"<<std::endl;
372
                os<<"\t\tif rst_i=\'1\' then"<<std::endl;
373
                os<<"\t\t\tgrant_reg<=(others=>\'0\');"<<std::endl;
374
                os<<"\t\telse"<<std::endl;
375
                os<<"\t\t\tgrant_reg<=grant;"<<std::endl;
376
                os<<"\t\tend if;"<<std::endl;
377
                os<<"\tend if;"<<std::endl;
378
                os<<"end process;"<<std::endl;
379
                os<<std::endl;
380
        }
381
        else {
382
                os<<"process (clk_i) is"<<std::endl;
383
                os<<"begin"<<std::endl;
384
                os<<"\tif rising_edge(clk_i) then"<<std::endl;
385
                os<<"\t\tif rst_i=\'1\' then"<<std::endl;
386
                os<<"\t\t\tgrant<=(others=>\'0\');"<<std::endl;
387
                os<<"\t\telsif (request and grant)="<<binaryLiteral(0,masters())<<" then"<<std::endl;
388
                os<<"\t\t\tgrant<=grant_next;"<<std::endl;
389
                os<<"\t\tend if;"<<std::endl;
390
                os<<"\tend if;"<<std::endl;
391
                os<<"end process;"<<std::endl;
392
                os<<std::endl;
393
        }
394
}
395
 
396
void Generator::writeMasterMux(std::ostream &os) {
397
        os<<"-- MASTER->SLAVE MUX"<<std::endl;
398
        os<<std::endl;
399
 
400
        if(masters()>1) {
401
                os<<"cyc_mux<=";
402
                for(int i=0;i<masters();i++) {
403
                        if(i>0) os<<'\t';
404
                        os<<"(s"<<i<<"_cyc_i and grant("<<i<<"))";
405
                        if(i<masters()-1) os<<" or"<<std::endl;
406
                        else os<<";"<<std::endl;
407
                }
408
                os<<std::endl;
409
 
410
                os<<"stb_mux<=";
411
                for(int i=0;i<masters();i++) {
412
                        if(i>0) os<<'\t';
413
                        os<<"(s"<<i<<"_stb_i and grant("<<i<<"))";
414
                        if(i<masters()-1) os<<" or"<<std::endl;
415
                        else os<<";"<<std::endl;
416
                }
417
                os<<std::endl;
418
 
419
                os<<"we_mux<=";
420
                for(int i=0;i<masters();i++) {
421
                        if(i>0) os<<'\t';
422
                        os<<"(s"<<i<<"_we_i and grant("<<i<<"))";
423
                        if(i<masters()-1) os<<" or"<<std::endl;
424
                        else os<<";"<<std::endl;
425
                }
426
                os<<std::endl;
427
 
428
                if(_selRange.valid()) {
429
                        os<<"sel_mux_gen: for i in sel_mux'range generate"<<std::endl;
430
                        os<<"\tsel_mux(i)<=";
431
                        for(int i=0;i<masters();i++) {
432
                                if(i>0) os<<"\t\t";
433
                                os<<"(s"<<i<<"_sel_i(i) and grant("<<i<<"))";
434
                                if(i<masters()-1) os<<" or"<<std::endl;
435
                                else os<<";"<<std::endl;
436
                        }
437
                        os<<"end generate;"<<std::endl;
438
                        os<<std::endl;
439
                }
440
 
441
                if(registeredFeedback()) {
442
                        os<<"cti_mux_gen: for i in cti_mux'range generate"<<std::endl;
443
                        os<<"\tcti_mux(i)<=";
444
                        for(int i=0;i<masters();i++) {
445
                                if(i>0) os<<"\t\t";
446
                                os<<"(s"<<i<<"_cti_i(i) and grant("<<i<<"))";
447
                                if(i<masters()-1) os<<" or"<<std::endl;
448
                                else os<<";"<<std::endl;
449
                        }
450
                        os<<"end generate;"<<std::endl;
451
                        os<<std::endl;
452
 
453
                        os<<"bte_mux_gen: for i in bte_mux'range generate"<<std::endl;
454
                        os<<"\tbte_mux(i)<=";
455
                        for(int i=0;i<masters();i++) {
456
                                if(i>0) os<<"\t\t";
457
                                os<<"(s"<<i<<"_bte_i(i) and grant("<<i<<"))";
458
                                if(i<masters()-1) os<<" or"<<std::endl;
459
                                else os<<";"<<std::endl;
460
                        }
461
                        os<<"end generate;"<<std::endl;
462
                        os<<std::endl;
463
                }
464
 
465
                os<<"adr_mux_gen: for i in adr_mux'range generate"<<std::endl;
466
                os<<"\tadr_mux(i)<=";
467
                for(int i=0;i<masters();i++) {
468
                        if(i>0) os<<"\t\t";
469
                        os<<"(s"<<i<<"_adr_i(i) and grant("<<i<<"))";
470
                        if(i<masters()-1) os<<" or"<<std::endl;
471
                        else os<<";"<<std::endl;
472
                }
473
                os<<"end generate;"<<std::endl;
474
                os<<std::endl;
475
 
476
                os<<"wdata_mux_gen: for i in wdata_mux'range generate"<<std::endl;
477
                os<<"\twdata_mux(i)<=";
478
                for(int i=0;i<masters();i++) {
479
                        if(i>0) os<<"\t\t";
480
                        os<<"(s"<<i<<"_dat_i(i) and grant("<<i<<"))";
481
                        if(i<masters()-1) os<<" or"<<std::endl;
482
                        else os<<";"<<std::endl;
483
                }
484
                os<<"end generate;"<<std::endl;
485
                os<<std::endl;
486
        }
487
        else { // just one master
488
                os<<"cyc_mux<=s0_cyc_i;"<<std::endl;
489
                os<<"stb_mux<=s0_stb_i;"<<std::endl;
490
                os<<"we_mux<=s0_we_i;"<<std::endl;
491
                if(_selRange.valid()) os<<"sel_mux<=s0_sel_i;"<<std::endl;
492
                if(registeredFeedback()) {
493
                        os<<"cti_mux<=s0_cti_i;"<<std::endl;
494
                        os<<"bte_mux<=s0_bte_i;"<<std::endl;
495
                }
496
                os<<"adr_mux<=s0_adr_i;"<<std::endl;
497
                os<<"wdata_mux<=s0_dat_i;"<<std::endl;
498
                os<<std::endl;
499
        }
500
}
501
 
502
void Generator::writeMasterDemux(std::ostream &os) {
503
        os<<"-- MASTER->SLAVE DEMUX"<<std::endl;
504
        os<<std::endl;
505
 
506
        if(slaves()>1) {
507
                os<<"select_slave<=";
508
                for(int i=0;i<slaves();i++) {
509
                        if(i>0) os<<'\t';
510
                        os<<decodedLiteral(i,_slavesRange.length());
511
                        os<<" when adr_mux("<<_slaveDecoderRange.toString()<<")=";
512
                        os<<binaryLiteral(i,_slaveDecoderRange.length())<<" else"<<std::endl;
513
                }
514
                if(_fallbackSlave) {
515
                        os<<'\t'<<decodedLiteral(slaves(),_slavesRange.length())<<
516
                                "; -- fallback slave"<<std::endl;
517
                }
518
                else os<<"\t(others=>'-');"<<std::endl;
519
                os<<std::endl;
520
 
521
                for(int i=0;i<slaves();i++) {
522
                        os<<'m'<<i<<"_cyc_o<=cyc_mux and select_slave("<<i<<");"<<std::endl;
523
                        os<<'m'<<i<<"_stb_o<=stb_mux and select_slave("<<i<<");"<<std::endl;
524
                        os<<'m'<<i<<"_we_o<=we_mux;"<<std::endl;
525
                        if(_selRange.valid()) os<<'m'<<i<<"_sel_o<=sel_mux;"<<std::endl;
526
                        if(registeredFeedback()) {
527
                                os<<'m'<<i<<"_cti_o<=cti_mux;"<<std::endl;
528
                                os<<'m'<<i<<"_bte_o<=bte_mux;"<<std::endl;
529
                        }
530
                        os<<'m'<<i<<"_adr_o<=adr_mux(m"<<i<<"_adr_o'range);"<<std::endl;
531
                        os<<'m'<<i<<"_dat_o<=wdata_mux;"<<std::endl;
532
                        os<<std::endl;
533
                }
534
        }
535
        else { // just one slave
536
                os<<"m0_cyc_o<=cyc_mux;"<<std::endl;
537
                os<<"m0_stb_o<=stb_mux;"<<std::endl;
538
                os<<"m0_we_o<=we_mux;"<<std::endl;
539
                if(_selRange.valid()) os<<"m0_sel_o<=sel_mux;"<<std::endl;
540
                if(registeredFeedback()) {
541
                        os<<"m0_cti_o<=cti_mux;"<<std::endl;
542
                        os<<"m0_bte_o<=bte_mux;"<<std::endl;
543
                }
544
                os<<"m0_adr_o<=adr_mux(m0_adr_o'range);"<<std::endl;
545
                os<<"m0_dat_o<=wdata_mux;"<<std::endl;
546
                os<<std::endl;
547
        }
548
}
549
 
550
void Generator::writeSlaveMux(std::ostream &os) {
551
        os<<"-- SLAVE->MASTER MUX"<<std::endl;
552
        os<<std::endl;
553
 
554
        if(slaves()>1) {
555
                os<<"ack_mux<=";
556
                for(int i=0;i<slaves();i++) {
557
                        if(i>0) os<<'\t';
558
                        os<<"(m"<<i<<"_ack_i and select_slave("<<i<<"))";
559
                        if(i<slaves()-1||_fallbackSlave) os<<" or"<<std::endl;
560
                        else os<<';'<<std::endl;
561
                }
562
                if(_fallbackSlave) {
563
                        os<<"\t(cyc_mux and stb_mux and select_slave("<<slaves()<<
564
                                ")); -- fallback slave"<<std::endl;
565
                }
566
                os<<std::endl;
567
 
568
                os<<"rdata_mux_gen: for i in rdata_mux'range generate"<<std::endl;
569
                os<<"\trdata_mux(i)<=";
570
                for(int i=0;i<slaves();i++) {
571
                        if(i>0) os<<"\t\t";
572
                        os<<"(m"<<i<<"_dat_i(i) and select_slave("<<i<<"))";
573
                        if(i<slaves()-1) os<<" or"<<std::endl;
574
                        else os<<";"<<std::endl;
575
                }
576
                os<<"end generate;"<<std::endl;
577
                os<<std::endl;
578
        }
579
        else { // just one slave
580
                os<<"ack_mux<=m0_ack_i;"<<std::endl;
581
                os<<"rdata_mux<=m0_dat_i;"<<std::endl;
582
                os<<std::endl;
583
        }
584
}
585
 
586
void Generator::writeSlaveDemux(std::ostream &os) {
587
        os<<"-- SLAVE->MASTER DEMUX"<<std::endl;
588
        os<<std::endl;
589
 
590
        if(masters()>1) {
591
                for(int i=0;i<masters();i++) {
592
                        os<<'s'<<i<<"_ack_o<=ack_mux and grant("<<i<<");"<<std::endl;
593
                        os<<'s'<<i<<"_dat_o<=rdata_mux;"<<std::endl;
594
                        os<<std::endl;
595
                }
596
        }
597
        else { // just one master
598
                os<<"s0_ack_o<=ack_mux;"<<std::endl;
599
                os<<"s0_dat_o<=rdata_mux;"<<std::endl;
600
                os<<std::endl;
601
        }
602
}
603
 
604
std::string Generator::binaryLiteral(int value,int n) {
605
        std::ostringstream oss;
606
        oss.put('\"');
607
        for(int i=n-1;i>=0;i--) {
608
                if(value>=static_cast<int>(sizeof(int)*8)) oss.put('0');
609
                else if((value>>i)&1) oss.put('1');
610
                else oss.put('0');
611
        }
612
        oss.put('\"');
613
        return oss.str();
614
}
615
 
616
std::string Generator::decodedLiteral(int value,int n) {
617
        std::ostringstream oss;
618
        oss.put('\"');
619
        for(int i=n-1;i>=0;i--) {
620
                if(value==i) oss.put('1');
621
                else oss.put('0');
622
        }
623
        oss.put('\"');
624
        return oss.str();
625
}

powered by: WebSVN 2.1.0

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