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

Subversion Repositories darkriscv

[/] [darkriscv/] [trunk/] [rtl/] [darksocv.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 marcelos
/*
2
 * Copyright (c) 2018, Marcelo Samsoniuk
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * * Neither the name of the copyright holder nor the names of its
16
 *   contributors may be used to endorse or promote products derived from
17
 *   this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
 
31
`timescale 1ns / 1ps
32
`include "../rtl/config.vh"
33
 
34
module darksocv
35
(
36
    input        XCLK,      // external clock
37
    input        XRES,      // external reset
38
 
39
    input        UART_RXD,  // UART receive line
40
    output       UART_TXD,  // UART transmit line
41
 
42
    output [3:0] LED,       // on-board leds
43
    output [3:0] DEBUG      // osciloscope
44
);
45
 
46
    // internal/external reset logic
47
 
48
    reg [7:0] IRES = -1;
49
 
50
`ifdef INVRES
51
    always@(posedge XCLK) IRES <= XRES==0 ? -1 : IRES[7] ? IRES-1 : 0; // reset low
52
`else
53
    always@(posedge XCLK) IRES <= XRES==1 ? -1 : IRES[7] ? IRES-1 : 0; // reset high
54
`endif
55
 
56
    // clock generator logic
57
 
58
`ifdef BOARD_CK_REF
59
 
60
    //`define BOARD_CK (`BOARD_CK_REF * `BOARD_CK_MUL / `BOARD_CK_DIV)
61
 
62
    wire LOCKED, CLKFB, CLK;
63
 
64
    // useful script to calculate MUL/DIV values:
65
    // 
66
    // awk 'BEGIN { for(m=2;m<=32;m++) for(d=1;d<=32;d++) print 66.666*m/d,m,d }' | sort -n
67
    // 
68
    // example: reference w/ 66MHz, m=19, d=13 and fx=97.4MHz. not so useful after I discovered 
69
    // that my evaluation board already has external clock generator :D
70
 
71
    `ifdef XILINX7CLK
72
 
73
       MMCME2_BASE #(
74
       .BANDWIDTH("OPTIMIZED"),   // Jitter programming (OPTIMIZED, HIGH, LOW)
75
       .CLKFBOUT_MULT_F(`BOARD_CK_MUL),     // Multiply value for all CLKOUT (2.000-64.000).
76
       .CLKFBOUT_PHASE(0.0),      // Phase offset in degrees of CLKFB (-360.000-360.000).
77
       .CLKIN1_PERIOD((1e9/`BOARD_CK_REF)),       // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
78
       // CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
79
       .CLKOUT0_DIVIDE_F(`BOARD_CK_DIV),    // Divide amount for CLKOUT0 (1.000-128.000).
80
       .CLKOUT1_DIVIDE(`BOARD_CK_DIV),
81
       .CLKOUT2_DIVIDE(`BOARD_CK_DIV),
82
       .CLKOUT3_DIVIDE(`BOARD_CK_DIV),
83
       .CLKOUT4_DIVIDE(`BOARD_CK_DIV),
84
       .CLKOUT5_DIVIDE(`BOARD_CK_DIV),
85
       .CLKOUT6_DIVIDE(`BOARD_CK_DIV),
86
       // CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
87
       .CLKOUT0_DUTY_CYCLE(0.5),
88
       .CLKOUT1_DUTY_CYCLE(0.5),
89
       .CLKOUT2_DUTY_CYCLE(0.5),
90
       .CLKOUT3_DUTY_CYCLE(0.5),
91
       .CLKOUT4_DUTY_CYCLE(0.5),
92
       .CLKOUT5_DUTY_CYCLE(0.5),
93
       .CLKOUT6_DUTY_CYCLE(0.5),
94
       // CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
95
       .CLKOUT0_PHASE(0.0),
96
       .CLKOUT1_PHASE(0.0),
97
       .CLKOUT2_PHASE(0.0),
98
       .CLKOUT3_PHASE(0.0),
99
       .CLKOUT4_PHASE(0.0),
100
       .CLKOUT5_PHASE(0.0),
101
       .CLKOUT6_PHASE(0.0),
102
       .CLKOUT4_CASCADE("FALSE"), // Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)
103
       .DIVCLK_DIVIDE(1),         // Master division value (1-106)
104
       .REF_JITTER1(0.0),         // Reference input jitter in UI (0.000-0.999).
105
       .STARTUP_WAIT("TRUE")     // Delays DONE until MMCM is locked (FALSE, TRUE)
106
    )
107
       MMCME2_BASE_inst (
108
           // Clock Outputs: 1-bit (each) output: User configurable clock outputs
109
           .CLKOUT0(CLK),     // 1-bit output: CLKOUT0
110
           //.CLKOUT0B(CLKOUT0B),   // 1-bit output: Inverted CLKOUT0
111
           //.CLKOUT1(CLKPWM),     // 1-bit output: CLKOUT1
112
           //.CLKOUT1B(CLKOUT1B),   // 1-bit output: Inverted CLKOUT1
113
           //.CLKOUT2(CLKOUT2),     // 1-bit output: CLKOUT2
114
           //.CLKOUT2B(CLKOUT2B),   // 1-bit output: Inverted CLKOUT2
115
           //.CLKOUT3(CLKOUT3),     // 1-bit output: CLKOUT3
116
           //.CLKOUT3B(CLKOUT3B),   // 1-bit output: Inverted CLKOUT3
117
           //.CLKOUT4(CLKOUT4),     // 1-bit output: CLKOUT4
118
           //.CLKOUT5(CLKOUT5),     // 1-bit output: CLKOUT5
119
           //.CLKOUT6(CLKOUT6),     // 1-bit output: CLKOUT6
120
           // Feedback Clocks: 1-bit (each) output: Clock feedback ports
121
           .CLKFBOUT(CLKFB),   // 1-bit output: Feedback clock
122
           //.CLKFBOUTB(CLKFBOUTB), // 1-bit output: Inverted CLKFBOUT
123
           // Status Ports: 1-bit (each) output: MMCM status ports
124
           .LOCKED(LOCKED),       // 1-bit output: LOCK
125
           // Clock Inputs: 1-bit (each) input: Clock input
126
           .CLKIN1(XCLK),       // 1-bit input: Clock
127
           // Control Ports: 1-bit (each) input: MMCM control ports
128
           .PWRDWN(1'b0),       // 1-bit input: Power-down
129
           .RST(IRES[7]),             // 1-bit input: Reset
130
           // Feedback Clocks: 1-bit (each) input: Clock feedback ports
131
           .CLKFBIN(CLKFB)      // 1-bit input: Feedback clock
132
        );
133
 
134
    `else
135
 
136
       DCM_SP #(
137
          .CLKDV_DIVIDE(2.0),                   // CLKDV divide value
138
                                                // (1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,9,10,11,12,13,14,15,16).
139
          .CLKFX_DIVIDE(`BOARD_CK_DIV),                     // Divide value on CLKFX outputs - D - (1-32)
140
          .CLKFX_MULTIPLY(`BOARD_CK_MUL),                   // Multiply value on CLKFX outputs - M - (2-32)
141
          .CLKIN_DIVIDE_BY_2("FALSE"),          // CLKIN divide by two (TRUE/FALSE)
142
          .CLKIN_PERIOD((1e9/`BOARD_CK_REF)),                  // Input clock period specified in nS
143
          .CLKOUT_PHASE_SHIFT("NONE"),          // Output phase shift (NONE, FIXED, VARIABLE)
144
          .CLK_FEEDBACK("1X"),                  // Feedback source (NONE, 1X, 2X)
145
          .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SYSTEM_SYNCHRNOUS or SOURCE_SYNCHRONOUS
146
          .DFS_FREQUENCY_MODE("LOW"),           // Unsupported - Do not change value
147
          .DLL_FREQUENCY_MODE("LOW"),           // Unsupported - Do not change value
148
          .DSS_MODE("NONE"),                    // Unsupported - Do not change value
149
          .DUTY_CYCLE_CORRECTION("TRUE"),       // Unsupported - Do not change value
150
          .FACTORY_JF(16'hc080),                // Unsupported - Do not change value
151
          .PHASE_SHIFT(0),                      // Amount of fixed phase shift (-255 to 255)
152
          .STARTUP_WAIT("FALSE")                // Delay config DONE until DCM_SP LOCKED (TRUE/FALSE)
153
       )
154
       DCM_SP_inst (
155
          //.CLK0(CLK0),         // 1-bit output: 0 degree clock output
156
          //.CLK180(CLK180),     // 1-bit output: 180 degree clock output
157
          //.CLK270(CLK270),     // 1-bit output: 270 degree clock output
158
          //.CLK2X(CLK2X),       // 1-bit output: 2X clock frequency clock output
159
          //.CLK2X180(CLK2X180), // 1-bit output: 2X clock frequency, 180 degree clock output
160
          //.CLK90(CLK90),       // 1-bit output: 90 degree clock output
161
          //.CLKDV(CLKDV),       // 1-bit output: Divided clock output
162
          .CLKFX(CLK),       // 1-bit output: Digital Frequency Synthesizer output (DFS)
163
          //.CLKFX180(CLKFX180), // 1-bit output: 180 degree CLKFX output
164
          .LOCKED(LOCKED),     // 1-bit output: DCM_SP Lock Output
165
          //.PSDONE(PSDONE),     // 1-bit output: Phase shift done output
166
          //.STATUS(STATUS),     // 8-bit output: DCM_SP status output
167
          //.CLKFB(CLKFB),       // 1-bit input: Clock feedback input
168
          .CLKIN(XCLK),       // 1-bit input: Clock input
169
          //.DSSEN(DSSEN),       // 1-bit input: Unsupported, specify to GND.
170
          //.PSCLK(PSCLK),       // 1-bit input: Phase shift clock input
171
          .PSEN(1'b0),         // 1-bit input: Phase shift enable
172
          //.PSINCDEC(PSINCDEC), // 1-bit input: Phase shift increment/decrement input
173
          .RST(IRES[7])            // 1-bit input: Active high reset input
174
       );
175
 
176
    `endif
177
 
178
    reg [7:0] DRES = -1;
179
 
180
    always@(posedge CLK)
181
    begin
182
        DRES <= LOCKED==0 ? -1 : DRES ? DRES-1 : 0;
183
    end
184
 
185
    wire RES = DRES[7];
186
 
187
`else
188
 
189
    // when there is no need for a clock generator:
190
 
191
    wire CLK = XCLK;
192
    wire RES = IRES[7];
193
`endif
194
    // ro/rw memories
195
 
196
`ifdef __HARVARD__
197
 
198
    reg [31:0] ROM [0:1023]; // ro memory
199
    reg [31:0] RAM [0:1023]; // rw memory
200
 
201
    // memory initialization
202
 
203
    integer i;
204
    initial
205
    begin
206
        for(i=0;i!=1024;i=i+1)
207
        begin
208
            ROM[i] = 32'd0;
209
            RAM[i] = 32'd0;
210
        end
211
 
212
        // workaround for vivado: no path in simulation and .mem extension
213
 
214
`ifdef XILINX_SIMULATOR
215
        $readmemh("darksocv.rom.mem",ROM);
216
        $readmemh("darksocv.ram.mem",RAM);
217
`else
218
        $readmemh("../src/darksocv.rom.mem",ROM);
219
        $readmemh("../src/darksocv.ram.mem",RAM);
220
`endif
221
    end
222
 
223
`else
224
 
225
    reg [31:0] MEM [0:2047]; // ro memory
226
 
227
    // memory initialization
228
 
229
    integer i;
230
    initial
231
    begin
232
        for(i=0;i!=2048;i=i+1)
233
        begin
234
            MEM[i] = 32'd0;
235
        end
236
 
237
        // workaround for vivado: no path in simulation and .mem extension
238
 
239
`ifdef XILINX_SIMULATOR
240
        $readmemh("darksocv.mem",MEM);
241
`else
242
        $readmemh("../src/darksocv.mem",MEM);
243
`endif
244
    end
245
 
246
`endif
247
 
248
    // darkriscv bus interface
249
 
250
    wire [31:0] IADDR;
251
    wire [31:0] DADDR;
252
    wire [31:0] IDATA;
253
    wire [31:0] DATAO;
254
    wire [31:0] DATAI;
255
    wire        WR,RD;
256
    wire [3:0]  BE;
257
 
258
`ifdef __FLEXBUZZ__
259
    wire [31:0] XATAO;
260
    wire [31:0] XATAI;
261
    wire [ 2:0] DLEN;
262
    wire        RW;
263
`endif
264
 
265
    wire [31:0] IOMUX [0:3];
266
 
267
    reg  [15:0] GPIOFF = 0;
268
    reg  [15:0] LEDFF  = 0;
269
 
270
    wire HLT;
271
 
272
`ifdef __ICACHE__
273
 
274
    // instruction cache
275
 
276
    reg  [55:0] ICACHE [0:63]; // instruction cache
277
    reg  [63:0] ITAG = 0;      // instruction cache tag
278
 
279
    wire [5:0]  IPTR    = IADDR[7:2];
280
    wire [55:0] ICACHEO = ICACHE[IPTR];
281
    wire [31:0] ICACHED = ICACHEO[31: 0]; // data
282
    wire [31:8] ICACHEA = ICACHEO[55:32]; // address
283
 
284
    wire IHIT = ITAG[IPTR] && ICACHEA==IADDR[31:8];
285
 
286
    reg  IFFX = 0;
287
    reg IFFX2 = 0;
288
 
289
    reg [31:0] ROMFF;
290
 
291
    always@(posedge CLK)
292
    begin
293
        ROMFF <= ROM[IADDR[11:2]];
294
 
295
        if(IFFX2)
296
        begin
297
            IFFX2 <= 0;
298
            IFFX  <= 0;
299
        end
300
        else
301
        if(!IHIT)
302
        begin
303
            ICACHE[IPTR] <= { IADDR[31:8], ROMFF };
304
            ITAG[IPTR]    <= IFFX; // cached!
305
            IFFX          <= 1;
306
            IFFX2         <= IFFX;
307
        end
308
    end
309
 
310
    assign IDATA = ICACHED;
311
 
312
`else
313
 
314
    reg [31:0] ROMFF;
315
 
316
`ifdef __WAITSTATES__
317
 
318
    reg [1:0] IHITACK = 0;
319
 
320
    wire IHIT = !(IHITACK!=1);
321
 
322
    always@(posedge CLK) // stage #1.0
323
    begin
324
        IHITACK <= RES ? 1 : IHITACK ? IHITACK-1 : 1; // wait-states
325
    end
326
`else
327
 
328
    wire IHIT = 1;
329
 
330
`endif
331
 
332
 
333
`ifdef __3STAGE__
334
 
335
    reg [31:0] ROMFF2 = 0;
336
    reg        HLT2   = 0;
337
 
338
    always@(posedge CLK) // stage #0.5    
339
    begin
340
        if(HLT)
341
        begin
342
            ROMFF2 <= ROMFF;
343
        end
344
 
345
        HLT2 <= HLT;
346
    end
347
 
348
    assign IDATA = HLT2 ? ROMFF2 : ROMFF;
349
`else
350
    assign IDATA = ROMFF;
351
`endif
352
 
353
    always@(posedge CLK) // stage #0.5    
354
    begin
355
`ifdef __HARVARD__
356
        ROMFF <= ROM[IADDR[11:2]];
357
`else
358
        ROMFF <= MEM[IADDR[12:2]];
359
`endif
360
    end
361
 
362
    //assign IDATA = ROM[IADDR[11:2]];
363
 
364
//    always@(posedge CLK)
365
//    begin   
366
//        // weird bug appears to be related to the "sw ra,12(sp)" instruction.
367
//        if(WR&&DADDR[31]==0&&DADDR[12]==0)
368
//        begin
369
//            ROMBUG <= IADDR;
370
//        end
371
//    end
372
 
373
//    assign IDATA = ROMFF;
374
 
375
`endif
376
 
377
`ifdef __DCACHE__
378
 
379
    // data cache
380
 
381
    reg  [55:0] DCACHE [0:63]; // data cache
382
    reg  [63:0] DTAG = 0;      // data cache tag
383
 
384
    wire [5:0]  DPTR    = DADDR[7:2];
385
    wire [55:0] DCACHEO = DCACHE[DPTR];
386
    wire [31:0] DCACHED = DCACHEO[31: 0]; // data
387
    wire [31:8] DCACHEA = DCACHEO[55:32]; // address
388
 
389
    wire DHIT = RD&&!DADDR[31]/*&&DADDR[12]*/ ? DTAG[DPTR] && DCACHEA==DADDR[31:8] : 1;
390
 
391
    reg   FFX = 0;
392
    reg  FFX2 = 0;
393
 
394
    reg [31:0] RAMFF;
395
 
396
    reg        WTAG    = 0;
397
    reg [31:0] WCACHEA = 0;
398
 
399
    wire WHIT = WR&&!DADDR[31]/*&&DADDR[12]*/ ? WTAG&&WCACHEA==DADDR : 1;
400
 
401
    always@(posedge CLK)
402
    begin
403
        RAMFF <= RAM[DADDR[11:2]];
404
 
405
        if(FFX2)
406
        begin
407
            FFX2 <= 0;
408
            FFX  <= 0;
409
            WCACHEA <= 0;
410
            WTAG <= 0;
411
        end
412
        else
413
        if(!WHIT)
414
        begin
415
            //individual byte/word/long selection, thanks to HYF!
416
            if(BE[0]) RAM[DADDR[11:2]][0 * 8 + 7: 0 * 8] <= DATAO[0 * 8 + 7: 0 * 8];
417
            if(BE[1]) RAM[DADDR[11:2]][1 * 8 + 7: 1 * 8] <= DATAO[1 * 8 + 7: 1 * 8];
418
            if(BE[2]) RAM[DADDR[11:2]][2 * 8 + 7: 2 * 8] <= DATAO[2 * 8 + 7: 2 * 8];
419
            if(BE[3]) RAM[DADDR[11:2]][3 * 8 + 7: 3 * 8] <= DATAO[3 * 8 + 7: 3 * 8];
420
 
421
            DCACHE[DPTR][0 * 8 + 7: 0 * 8] <= BE[0] ? DATAO[0 * 8 + 7: 0 * 8] : RAMFF[0 * 8 + 7: 0 * 8];
422
            DCACHE[DPTR][1 * 8 + 7: 1 * 8] <= BE[1] ? DATAO[1 * 8 + 7: 1 * 8] : RAMFF[1 * 8 + 7: 1 * 8];
423
            DCACHE[DPTR][2 * 8 + 7: 2 * 8] <= BE[2] ? DATAO[2 * 8 + 7: 2 * 8] : RAMFF[2 * 8 + 7: 2 * 8];
424
            DCACHE[DPTR][3 * 8 + 7: 3 * 8] <= BE[3] ? DATAO[3 * 8 + 7: 3 * 8] : RAMFF[3 * 8 + 7: 3 * 8];
425
 
426
            DCACHE[DPTR][55:32] <= DADDR[31:8];
427
 
428
            //DCACHE[DPTR] <= { DADDR[31:8],
429
            //                        BE[3] ? DATAO[3 * 8 + 7: 3 * 8] : RAMFF[3 * 8 + 7: 3 * 8],
430
            //                        BE[2] ? DATAO[2 * 8 + 7: 2 * 8] : RAMFF[2 * 8 + 7: 2 * 8],
431
            //                        BE[1] ? DATAO[1 * 8 + 7: 1 * 8] : RAMFF[1 * 8 + 7: 1 * 8],
432
            //                        BE[0] ? DATAO[0 * 8 + 7: 0 * 8] : RAMFF[0 * 8 + 7: 0 * 8]
433
            //                };
434
 
435
            DTAG[DPTR]   <= FFX; // cached!
436
            WTAG         <= FFX;
437
 
438
            WCACHEA      <= DADDR;
439
 
440
            FFX          <= 1;
441
            FFX2         <= FFX;
442
        end
443
        else
444
        if(!DHIT)
445
        begin
446
            DCACHE[DPTR] <= { DADDR[31:8], RAMFF };
447
            DTAG[DPTR]   <= FFX; // cached!
448
            FFX          <= 1;
449
            FFX2         <= FFX;
450
        end
451
    end
452
 
453
    assign DATAI = DADDR[31] ? IOMUX[DADDR[3:2]] : DCACHED;
454
 
455
`else
456
 
457
    // no cache!
458
 
459
    `ifdef __FLEXBUZZ__
460
 
461
    // must work just exactly as the default interface, since we have no
462
    // flexbuzz devices available yet (i.e., all devices are 32-bit now)
463
 
464
    assign XATAI = DLEN[0] ? ( DADDR[1:0]==3 ? DATAI[31:24] :
465
                               DADDR[1:0]==2 ? DATAI[23:16] :
466
                               DADDR[1:0]==1 ? DATAI[15: 8] :
467
                                               DATAI[ 7: 0] ):
468
                   DLEN[1] ? ( DADDR[1]==1   ? DATAI[31:16] :
469
                                               DATAI[15: 0] ):
470
                                               DATAI;
471
 
472
    assign DATAO = DLEN[0] ? ( DADDR[1:0]==3 ? {        XATAO[ 7: 0], 24'hx } :
473
                               DADDR[1:0]==2 ? {  8'hx, XATAO[ 7: 0], 16'hx } :
474
                               DADDR[1:0]==1 ? { 16'hx, XATAO[ 7: 0],  8'hx } :
475
                                               { 24'hx, XATAO[ 7: 0]        } ):
476
                   DLEN[1] ? ( DADDR[1]==1   ? { XATAO[15: 0], 16'hx } :
477
                                               { 16'hx, XATAO[15: 0] } ):
478
                                                 XATAO;
479
 
480
    assign RD = DLEN&&RW==1;
481
    assign WR = DLEN&&RW==0;
482
 
483
    assign BE =    DLEN[0] ? ( DADDR[1:0]==3 ? 4'b1000 : // 8-bit
484
                               DADDR[1:0]==2 ? 4'b0100 :
485
                               DADDR[1:0]==1 ? 4'b0010 :
486
                                               4'b0001 ) :
487
                   DLEN[1] ? ( DADDR[1]==1   ? 4'b1100 : // 16-bit
488
                                               4'b0011 ) :
489
                                               4'b1111;  // 32-bit
490
 
491
    `endif
492
 
493
    reg [31:0] RAMFF;
494
`ifdef __WAITSTATES__
495
 
496
    reg [1:0] DACK = 0;
497
 
498
    wire WHIT = 1;
499
    wire DHIT = !((WR||RD) && DACK!=1);
500
 
501
    always@(posedge CLK) // stage #1.0
502
    begin
503
        DACK <= RES ? 0 : DACK ? DACK-1 : (RD||WR) ? 1 : 0; // wait-states
504
    end
505
 
506
`elsif __3STAGE__
507
 
508
    // for single phase clock: 1 wait state in read op always required!
509
 
510
    reg [1:0] DACK = 0;
511
 
512
    wire WHIT = 1;
513
    wire DHIT = !((RD||WR) && DACK!=1); // the WR operatio does not need ws. in this config.
514
 
515
    always@(posedge CLK) // stage #1.0
516
    begin
517
        DACK <= RES ? 0 : DACK ? DACK-1 : (RD||WR) ? 1 : 0; // wait-states
518
    end
519
 
520
`else
521
 
522
    // for dual phase clock: 0 wait state
523
 
524
    wire WHIT = 1;
525
    wire DHIT = 1;
526
 
527
`endif
528
 
529
    always@(posedge CLK) // stage #1.5
530
    begin
531
`ifdef __HARVARD__
532
        RAMFF <= RAM[DADDR[11:2]];
533
`else
534
        RAMFF <= MEM[DADDR[12:2]];
535
`endif
536
    end
537
 
538
    //assign DATAI = DADDR[31] ? IOMUX  : RAM[DADDR[11:2]];
539
 
540
    reg [31:0] IOMUXFF;
541
 
542
    //individual byte/word/long selection, thanks to HYF!
543
 
544
    always@(posedge CLK)
545
    begin
546
 
547
`ifdef __3STAGE__
548
 
549
        // read-modify-write operation w/ 1 wait-state:
550
 
551
        if(!HLT&&WR&&DADDR[31]==0/*&&DADDR[12]==1*/)
552
        begin
553
    `ifdef __HARVARD__
554
            RAM[DADDR[11:2]] <=
555
    `else
556
            MEM[DADDR[12:2]] <=
557
    `endif
558
                                {
559
                                    BE[3] ? DATAO[3 * 8 + 7: 3 * 8] : RAMFF[3 * 8 + 7: 3 * 8],
560
                                    BE[2] ? DATAO[2 * 8 + 7: 2 * 8] : RAMFF[2 * 8 + 7: 2 * 8],
561
                                    BE[1] ? DATAO[1 * 8 + 7: 1 * 8] : RAMFF[1 * 8 + 7: 1 * 8],
562
                                    BE[0] ? DATAO[0 * 8 + 7: 0 * 8] : RAMFF[0 * 8 + 7: 0 * 8]
563
                                };
564
        end
565
 
566
`else
567
        // write-only operation w/ 0 wait-states:
568
    `ifdef __HARVARD__
569
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[3]) RAM[DADDR[11:2]][3 * 8 + 7: 3 * 8] <= DATAO[3 * 8 + 7: 3 * 8];
570
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[2]) RAM[DADDR[11:2]][2 * 8 + 7: 2 * 8] <= DATAO[2 * 8 + 7: 2 * 8];
571
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[1]) RAM[DADDR[11:2]][1 * 8 + 7: 1 * 8] <= DATAO[1 * 8 + 7: 1 * 8];
572
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[0]) RAM[DADDR[11:2]][0 * 8 + 7: 0 * 8] <= DATAO[0 * 8 + 7: 0 * 8];
573
    `else
574
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[3]) MEM[DADDR[12:2]][3 * 8 + 7: 3 * 8] <= DATAO[3 * 8 + 7: 3 * 8];
575
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[2]) MEM[DADDR[12:2]][2 * 8 + 7: 2 * 8] <= DATAO[2 * 8 + 7: 2 * 8];
576
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[1]) MEM[DADDR[12:2]][1 * 8 + 7: 1 * 8] <= DATAO[1 * 8 + 7: 1 * 8];
577
        if(WR&&DADDR[31]==0&&/*DADDR[12]==1&&*/BE[0]) MEM[DADDR[12:2]][0 * 8 + 7: 0 * 8] <= DATAO[0 * 8 + 7: 0 * 8];
578
    `endif
579
`endif
580
 
581
        IOMUXFF <= IOMUX[DADDR[3:2]]; // read w/ 2 wait-states
582
    end
583
 
584
    //assign DATAI = DADDR[31] ? IOMUX[DADDR[3:2]]  : RAMFF;
585
    assign DATAI = DADDR[31] ? /*IOMUX[DADDR[3:2]]*/ IOMUXFF  : RAMFF;
586
 
587
`endif
588
 
589
    // io for debug
590
 
591
    reg [7:0] IREQ = 0;
592
    reg [7:0] IACK = 0;
593
 
594
    reg [31:0] TIMERFF;
595
 
596
    wire [7:0] BOARD_IRQ;
597
 
598
    wire   [7:0] BOARD_ID = `BOARD_ID;              // board id
599
    wire   [7:0] BOARD_CM = (`BOARD_CK/1000000);    // board clock (MHz)
600
    wire   [7:0] BOARD_CK = (`BOARD_CK/10000)%100;  // board clock (kHz)
601
 
602
    assign IOMUX[0] = { BOARD_IRQ, BOARD_CK, BOARD_CM, BOARD_ID };
603
    //assign IOMUX[1] = from UART!
604
    assign IOMUX[2] = { GPIOFF, LEDFF };
605
    assign IOMUX[3] = TIMERFF;
606
 
607
    reg [31:0] TIMER = 0;
608
 
609
    reg XTIMER = 0;
610
 
611
    always@(posedge CLK)
612
    begin
613
        if(WR&&DADDR[31]&&DADDR[3:0]==4'b1000)
614
        begin
615
            LEDFF <= DATAO[15:0];
616
        end
617
 
618
        if(WR&&DADDR[31]&&DADDR[3:0]==4'b1010)
619
        begin
620
            GPIOFF <= DATAO[31:16];
621
        end
622
 
623
        if(RES)
624
            TIMERFF <= (`BOARD_CK/1000000)-1; // timer set to 1MHz by default
625
        else
626
        if(WR&&DADDR[31]&&DADDR[3:0]==4'b1100)
627
        begin
628
            TIMERFF <= DATAO[31:0];
629
        end
630
 
631
        if(RES)
632
            IACK <= 0;
633
        else
634
        if(WR&&DADDR[31]&&DADDR[3:0]==4'b0011)
635
        begin
636
            //$display("clear io.irq = %x (ireq=%x, iack=%x)",DATAO[32:24],IREQ,IACK);
637
 
638
            IACK[7] <= DATAO[7+24] ? IREQ[7] : IACK[7];
639
            IACK[6] <= DATAO[6+24] ? IREQ[6] : IACK[6];
640
            IACK[5] <= DATAO[5+24] ? IREQ[5] : IACK[5];
641
            IACK[4] <= DATAO[4+24] ? IREQ[4] : IACK[4];
642
            IACK[3] <= DATAO[3+24] ? IREQ[3] : IACK[3];
643
            IACK[2] <= DATAO[2+24] ? IREQ[2] : IACK[2];
644
            IACK[1] <= DATAO[1+24] ? IREQ[1] : IACK[1];
645
            IACK[0] <= DATAO[0+24] ? IREQ[0] : IACK[0];
646
        end
647
 
648
        if(RES)
649
            IREQ <= 0;
650
        else
651
        if(TIMERFF)
652
        begin
653
            TIMER <= TIMER ? TIMER-1 : TIMERFF;
654
 
655
            if(TIMER==0 && IREQ==IACK)
656
            begin
657
                IREQ[7] <= !IACK[7];
658
 
659
                //$display("timr0 set");
660
            end
661
 
662
            XTIMER  <= XTIMER+(TIMER==0);
663
        end
664
    end
665
 
666
    assign BOARD_IRQ = IREQ^IACK;
667
 
668
    assign HLT = !IHIT||!DHIT||!WHIT;
669
 
670
    // darkuart
671
 
672
    wire [3:0] UDEBUG;
673
 
674
    darkuart
675
//    #( 
676
//      .BAUD((`BOARD_CK/115200))
677
//    )
678
    uart0
679
    (
680
      .CLK(CLK),
681
      .RES(RES),
682
      .RD(!HLT&&RD&&DADDR[31]&&DADDR[3:2]==1),
683
      .WR(!HLT&&WR&&DADDR[31]&&DADDR[3:2]==1),
684
      .BE(BE),
685
      .DATAI(DATAO),
686
      .DATAO(IOMUX[1]),
687
      //.IRQ(BOARD_IRQ[1]),
688
      .RXD(UART_RXD),
689
      .TXD(UART_TXD),
690
      .DEBUG(UDEBUG)
691
    );
692
 
693
    // darkriscv
694
 
695
    wire [3:0] KDEBUG;
696
 
697
    darkriscv
698
//    #(
699
//        .RESET_PC(32'h00000000),
700
//        .RESET_SP(32'h00002000)
701
//    ) 
702
    core0
703
    (
704
`ifdef __3STAGE__
705
        .CLK(CLK),
706
`else
707
        .CLK(!CLK),
708
`endif
709
        .RES(RES),
710
        .HLT(HLT),
711
`ifdef __THREADING__
712
        .IREQ(|(IREQ^IACK)),
713
`endif
714
        .IDATA(IDATA),
715
        .IADDR(IADDR),
716
        .DADDR(DADDR),
717
 
718
`ifdef __FLEXBUZZ__
719
        .DATAI(XATAI),
720
        .DATAO(XATAO),
721
        .DLEN(DLEN),
722
        .RW(RW),
723
`else
724
        .DATAI(DATAI),
725
        .DATAO(DATAO),
726
        .BE(BE),
727
        .WR(WR),
728
        .RD(RD),
729
`endif
730
 
731
        .DEBUG(KDEBUG)
732
    );
733
 
734
`ifdef __ICARUS__
735
  initial
736
  begin
737
    $dumpfile("darksocv.vcd");
738
    $dumpvars();
739
  end
740
`endif
741
 
742
    assign LED   = LEDFF[3:0];
743
 
744
    assign DEBUG = { GPIOFF[0], XTIMER, WR, RD }; // UDEBUG;
745
 
746
endmodule

powered by: WebSVN 2.1.0

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