OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_peripheral/] [ram/] [wb_bram_ctrl.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/**********************************************************************
2
**      File:  wb_bram_ctrl.v
3
**
4
**
5
**      Copyright (C) 2014-2017  Alireza Monemi
6
**
7
**      This file is part of ProNoC
8
**
9
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
10
**      you can redistribute it and/or modify it under the terms of the GNU
11
**      Lesser General Public License as published by the Free Software Foundation,
12
**      either version 2 of the License, or (at your option) any later version.
13
**
14
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
15
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
17
**      Public License for more details.
18
**
19
**      You should have received a copy of the GNU Lesser General Public
20
**      License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
21
**
22
**
23
**      Description:
24
**      memory wishbone bus interface controller
25
**
26
**
27
*******************************************************************/
28
 
29
// synthesis translate_off
30
`timescale 1ns / 1ps
31
// synthesis translate_on
32
 
33
 
34
module wb_bram_ctrl #(
35
    parameter Dw=32, //RAM data_width in bits
36
    parameter Aw=10, //RAM address width
37
 
38
    // wishbon bus param
39
    parameter BURST_MODE = "DISABLED", // "DISABLED" , "ENABLED" wisbone bus burst mode 
40
    parameter SELw = Dw/8,
41
    parameter CTIw = 3,
42
    parameter BTEw = 2
43
)(
44
    clk,
45
    reset,
46
 
47
     //wishbone bus interface
48
    sa_dat_i,
49
    sa_sel_i,
50
    sa_addr_i,
51
    sa_cti_i,
52
    sa_bte_i,
53
    sa_stb_i,
54
    sa_cyc_i,
55
    sa_we_i,
56
    sa_dat_o,
57
    sa_ack_o,
58
    sa_err_o,
59
    sa_rty_o,
60
 
61
    // BRAM interface 
62
    byteena_a,
63
    d,
64
    addr,
65
    we,
66
    q
67
 
68
 
69
);
70
 
71
    input            clk;
72
    input            reset;
73
 
74
   // BRAM interface 
75
    output   [Dw-1   :   0]  d;
76
    output   [Aw-1   :   0]  addr;
77
    output                 we;
78
    input  [Dw-1    :   0]  q;
79
    output [SELw-1 :   0]  byteena_a;
80
 
81
// Wishbone bus interface
82
    input       [Dw-1       :   0]      sa_dat_i;
83
    input       [SELw-1     :   0]      sa_sel_i;
84
    input       [Aw-1       :   0]      sa_addr_i;
85
 
86
    input                      sa_stb_i;
87
    input                      sa_cyc_i;
88
    input                      sa_we_i;
89
    input       [CTIw-1     :   0]      sa_cti_i;
90
    input       [BTEw-1     :   0]      sa_bte_i;
91
 
92
 
93
    output     [Dw-1       :   0]      sa_dat_o;
94
    output                    sa_ack_o;
95
    output                     sa_err_o;
96
    output                     sa_rty_o;
97
 
98
    wire sa_ack;
99
 
100
 
101
    // 3'b100 is reserved in wb4 interface. It is used for ni
102
   // wire sa_ack_ni_burst =   sa_stb_i ; //the ack is registerd inside the master in burst mode 
103
  //  assign sa_ack_o = (sa_cti_i == 3'b100 ) ?  sa_ack_ni_burst: sa_ack;
104
 
105
    assign sa_ack_o =  sa_ack;
106
 
107
    generate if (BURST_MODE== "ENABLED") begin : burst_wb
108
        //assign byteena_a = sa_sel_i;// {SELw{1'b1}}; // byte enable has been supported by the bram controller 
109
        wb_burst_bram_ctrl #(
110
                .Dw(Dw),
111
                .Aw(Aw),
112
                .SELw(SELw),
113
                .CTIw(CTIw),
114
                .BTEw(BTEw)
115
        )
116
        bram_ctrl
117
        (
118
                .clk(clk),
119
                .reset(reset),
120
                .d(d),
121
                .addr(addr),
122
                .we(we),
123
                .byteen(byteena_a),
124
                .q(q),
125
                .sa_dat_i(sa_dat_i),
126
                .sa_sel_i(sa_sel_i),
127
                .sa_addr_i(sa_addr_i),
128
                .sa_stb_i(sa_stb_i),
129
                .sa_cyc_i(sa_cyc_i),
130
                .sa_we_i(sa_we_i),
131
                .sa_cti_i(sa_cti_i),
132
                .sa_bte_i(sa_bte_i),
133
                .sa_dat_o(sa_dat_o),
134
                .sa_ack_o(sa_ack),
135
                .sa_err_o(sa_err_o),
136
                .sa_rty_o(sa_rty_o)
137
     );
138
 
139
    end else begin : no_burst
140
 
141
 
142
     assign sa_dat_o =   q;
143
     assign d     =   sa_dat_i ;
144
     assign addr     =   sa_addr_i;
145
     assign we       =   sa_stb_i &  sa_we_i;
146
     assign sa_err_o =   1'b0;
147
     assign sa_rty_o =   1'b0;
148
     assign byteena_a= sa_sel_i;
149
 
150
     reg ack;
151
     assign sa_ack = ack;
152
 
153
     always @(posedge clk ) begin
154
         if(reset) begin
155
          ack  <= 1'b0;
156
         end else begin
157
          ack  <= (~sa_ack_o) & sa_stb_i;
158
         end
159
     end
160
 
161
    end
162
    endgenerate
163
 
164
endmodule
165
 
166
 
167
 
168
 
169
 
170
 
171
 
172
 
173
 
174
module wb_burst_bram_ctrl #(
175
 
176
        parameter Dw=32, //RAM data_width in bits
177
        parameter Aw=10, //RAM address width
178
 
179
        // wishbon bus param
180
        parameter       SELw   = Dw/8,
181
        parameter       CTIw   = 3,
182
        parameter   BTEw   = 2
183
 
184
)(
185
        clk,
186
        reset,
187
 
188
         //wishbone bus interface
189
        sa_dat_i,
190
        sa_sel_i,
191
        sa_addr_i,
192
        sa_cti_i,
193
        sa_bte_i,
194
        sa_stb_i,
195
        sa_cyc_i,
196
        sa_we_i,
197
        sa_dat_o,
198
        sa_ack_o,
199
        sa_err_o,
200
        sa_rty_o,
201
 
202
        // BRAM interface 
203
        byteen,
204
        d,
205
        addr,
206
        we,
207
        q
208
 
209
 
210
);
211
 
212
    `define UDLY  1
213
 
214
        input            clk;
215
        input            reset;
216
 
217
   // BRAM interface 
218
        output   [Dw-1   :   0]  d;
219
        output   [Aw-1   :   0]  addr;
220
        output                                           we;
221
        input  [Dw-1    :   0]  q;
222
 
223
 
224
 
225
        // Wishbone bus interface
226
        input       [Dw-1       :   0]      sa_dat_i;
227
        input       [SELw-1     :   0]      sa_sel_i;
228
        input       [Aw-1       :   0]      sa_addr_i;
229
 
230
        input                      sa_stb_i;
231
        input                      sa_cyc_i;
232
        input                      sa_we_i;
233
        input       [CTIw-1     :   0]      sa_cti_i;
234
        input       [BTEw-1     :   0]      sa_bte_i;
235
 
236
 
237
        output  reg   [Dw-1       :   0]      sa_dat_o;
238
        output  reg                  sa_ack_o;
239
        output  reg                   sa_err_o;
240
        output  reg                   sa_rty_o;
241
 
242
        output [SELw-1 : 0] byteen;
243
 
244
    //Burst Type Extension for Incrementing and Decrementing bursts
245
    localparam [1:0]
246
        LINEAR  = 2'b00,
247
        FOUR_BEAT =2'b01,
248
        EIGHT_BEAT=2'b10,
249
        SIXTEEN_BEAT =2'b11;
250
 
251
 
252
 
253
 
254
 
255
 
256
   localparam [2:0] ST_IDLE  = 3'b000,
257
                        ST_BURST = 3'b001,
258
                        ST_END   = 3'b010,
259
                        ST_SUBRD = 3'b100,
260
                        ST_SUB   = 3'b101,
261
                        ST_SUBWR = 3'b110;
262
 
263
 
264
 
265
 
266
         /*----------------------------------------------------------------------
267
          Internal Nets and Registers
268
          ----------------------------------------------------------------------*/
269
         wire [Dw-1:0] data;      // Data read from RAM
270
         reg                     write_enable; // RAM write enable
271
         reg [Dw-1:0]  write_data, write_data_d;   // RAM write data
272
         reg [Aw+1:0]  pmi_address,  pmi_address_nxt;
273
         reg [Aw+1:0]  adr_linear_incr,adr_4_beat,adr_8_beat,adr_16_beat;
274
 
275
         reg [Aw-1:0]  read_address, write_address;
276
         reg                     sa_ack_o_nxt;
277
         reg [Dw-1:0]  read_data;
278
        // reg                   read_enable;
279
         reg                     raw_hazard, raw_hazard_nxt;
280
         reg [Dw-1:0]  sa_dat_i_d;
281
         reg [3:0]                sa_sel_i_d;
282
         reg                     delayed_write;
283
 
284
         wire [Aw+1 : 0] addr_init = {sa_addr_i,2'b00};
285
         /*----------------------------------------------------------------------
286
          State Machine
287
          ----------------------------------------------------------------------*/
288
         reg [2:0] state, state_nxt;
289
 
290
         always @(*)
291
           case (state)
292
             ST_IDLE:
293
               if (sa_stb_i && sa_cyc_i && (sa_ack_o == 1'b0))
294
                 if(sa_cti_i ==3'b100)
295
                        state_nxt = ST_IDLE;
296
                 else if ((sa_cti_i == 3'b000) || (sa_cti_i == 3'b111) )
297
                   state_nxt = ST_END;
298
                 else
299
                   if (sa_we_i && (sa_sel_i != 4'b1111))
300
                     state_nxt = ST_SUBRD;
301
                   else
302
                     state_nxt = ST_BURST;
303
               else
304
                 state_nxt = state;
305
 
306
             ST_BURST:
307
               if (sa_cti_i == 3'b111)
308
                 state_nxt = ST_IDLE;
309
               else
310
                 state_nxt = state;
311
 
312
             ST_SUBRD:
313
               state_nxt = ST_SUB;
314
 
315
             ST_SUB:
316
               if (sa_cti_i == 3'b111)
317
                 state_nxt = ST_SUBWR;
318
               else
319
                 state_nxt = state;
320
 
321
             default:
322
               state_nxt = ST_IDLE;
323
           endcase
324
 
325
         /*----------------------------------------------------------------------
326
 
327
          ----------------------------------------------------------------------*/
328
         always @(*)
329
           if ((state == ST_SUB) && (read_address == write_address))
330
             raw_hazard_nxt = 1'b1;
331
           else
332
             raw_hazard_nxt = 1'b0;
333
 
334
         /*----------------------------------------------------------------------
335
          Set up read to EBR
336
          ----------------------------------------------------------------------*/
337
         always @(*)
338
           begin
339
           /*
340
              if ((sa_we_i == 1'b0)
341
                  || (sa_we_i
342
                      && (((state == ST_IDLE) && ((sa_cti_i == 3'b000) || (sa_cti_i == 3'b111) || (sa_sel_i != 4'b1111)))
343
                          || (state == ST_SUBRD)
344
                          || ((state == ST_SUB) && (raw_hazard_nxt == 1'b0)))))
345
                read_enable = 1'b1;
346
              else
347
                read_enable = 1'b0;
348
              */
349
              read_data = raw_hazard ? write_data_d : data;
350
           end
351
 
352
         /*----------------------------------------------------------------------
353
          Set up write to EBR
354
          ----------------------------------------------------------------------*/
355
         always @(*)
356
           begin
357
              if ((sa_we_i
358
                   && (// Word Burst Write (first write in a sequence)
359
                       ((state == ST_IDLE)
360
                        && sa_cyc_i && sa_stb_i && (sa_cti_i != 3'b000) && (sa_cti_i !=3'b100) && (sa_cti_i != 3'b111) && (sa_sel_i == 4'b1111))
361
                       // Single Write
362
                       || (state == ST_END)
363
                       // Burst Write (all writes beyond first write)
364
                       || (state == ST_BURST)))
365
                  // Sub-Word Burst Write
366
                  || ((state == ST_SUB) || (state == ST_SUBWR)))
367
                write_enable = 1'b1;
368
              else
369
                write_enable = 1'b0;
370
 
371
              if ((state == ST_SUBRD) || (state == ST_SUB) || (state == ST_SUBWR))
372
                delayed_write = 1'b1;
373
              else
374
                delayed_write = 1'b0;
375
 
376
              write_data[7:0]   = (delayed_write
377
                                   ? (sa_sel_i_d[0] ? sa_dat_i_d[7:0] : read_data[7:0])
378
                                   : (sa_sel_i[0] ? sa_dat_i[7:0] : data[7:0]));
379
              write_data[15:8]  = (delayed_write
380
                                   ? (sa_sel_i_d[1] ? sa_dat_i_d[15:8] : read_data[15:8])
381
                                   : (sa_sel_i[1] ? sa_dat_i[15:8] : data[15:8]));
382
              write_data[23:16] = (delayed_write
383
                                   ? (sa_sel_i_d[2] ? sa_dat_i_d[23:16] : read_data[23:16])
384
                                   : (sa_sel_i[2] ? sa_dat_i[23:16] : data[23:16]));
385
              write_data[31:24] = (delayed_write
386
                                   ? (sa_sel_i_d[3] ? sa_dat_i_d[31:24] : read_data[31:24])
387
                                   : (sa_sel_i[3] ? sa_dat_i[31:24] : data[31:24]));
388
           end
389
 
390
 
391
    /*----------------------------------------------------------------------
392
        Set up address to EBR
393
        ----------------------------------------------------------------------*/
394
        always @(*) begin
395
        if (// First address of any access is obtained from Wishbone signals
396
                  (state == ST_IDLE)
397
                  // Read for a Sub-Word Wishbone Burst Write
398
                  || (state == ST_SUB)) read_address = sa_addr_i;
399
        else read_address = pmi_address[Aw+1:2];
400
 
401
        if ((state == ST_SUB) || (state == ST_SUBWR))  write_address = pmi_address[Aw+1:2];
402
        else write_address = sa_addr_i;
403
 
404
        // Keep track of first address and subsequently increment it by 4
405
        // bytes on a burst read
406
            if (sa_we_i) begin
407
                //pmi_address_nxt = sa_addr_i[Aw+1:0];
408
            adr_linear_incr= addr_init;
409
            adr_4_beat= addr_init;
410
            adr_8_beat= addr_init;
411
            adr_16_beat=addr_init;
412
            end else
413
            if (state == ST_IDLE)
414
                if ((sa_sel_i == 4'b1000) || (sa_sel_i == 4'b0100) || (sa_sel_i == 4'b0010) || (sa_sel_i == 4'b0001))begin
415
                            //pmi_address_nxt = sa_addr_i[Aw+1:0] + 1'b1;
416
                            adr_linear_incr= addr_init + 1'b1;
417
                    adr_4_beat= {addr_init[Aw+1 :4], addr_init[3:0] + 1'b1};
418
                    adr_8_beat= {addr_init[Aw+1 :5], addr_init[4:0] + 1'b1};
419
                    adr_16_beat={addr_init[Aw+1 :6], addr_init[5:0] + 1'b1};
420
                end else if ((sa_sel_i == 4'b1100) || (sa_sel_i == 4'b0011))begin
421
                    //pmi_address_nxt = {(sa_addr_i[Aw+1:1] + 1'b1), 1'b0};
422
                    adr_linear_incr= {(addr_init[Aw+1:1]  + 1'b1), 1'b0};
423
                    adr_4_beat= {addr_init[Aw+1 :4], {addr_init[3:1] +1'b1},1'b0};
424
                    adr_8_beat= {addr_init[Aw+1 :5], {addr_init[4:1] +1'b1},1'b0};
425
                    adr_16_beat={addr_init[Aw+1 :6], {addr_init[5:1] +1'b1},1'b0};
426
               end else begin
427
                           //pmi_address_nxt = {(sa_addr_i[Aw+1:2] + 1'b1), 2'b00};
428
                            adr_linear_incr= {(addr_init[Aw+1:2]  + 1'b1), 2'b00};
429
                            adr_4_beat= {addr_init[Aw+1 :4], {addr_init[3:2] +1'b1},2'b00};
430
                    adr_8_beat= {addr_init[Aw+1 :5], {addr_init[4:2] +1'b1},2'b00};
431
                    adr_16_beat={addr_init[Aw+1 :6], {addr_init[5:2] +1'b1},2'b00};
432
                       end
433
                  else
434
                  if ((sa_sel_i == 4'b1000) || (sa_sel_i == 4'b0100) || (sa_sel_i == 4'b0010) || (sa_sel_i == 4'b0001))begin
435
                    //pmi_address_nxt_linear_incr = pmi_address + 1'b1;
436
                    adr_linear_incr= pmi_address + 1'b1;
437
                    adr_4_beat= {pmi_address[Aw+1 :4], pmi_address[3:0] + 1'b1};
438
                    adr_8_beat= {pmi_address[Aw+1 :5], pmi_address[4:0] + 1'b1};
439
                    adr_16_beat={pmi_address[Aw+1 :6], pmi_address[5:0] + 1'b1};
440
                  end else if ((sa_sel_i == 4'b1100) || (sa_sel_i == 4'b0011)) begin
441
                       // pmi_address_nxt = {pmi_address[Aw+1:1] + 1'b1), 1'b0};
442
                        adr_linear_incr= {(pmi_address[Aw+1:1] + 1'b1), 1'b0};
443
                        adr_4_beat= {pmi_address[Aw+1 :4], {pmi_address[3:1] + 1'b1},1'b0};
444
                    adr_8_beat= {pmi_address[Aw+1 :5], {pmi_address[4:1] + 1'b1},1'b0};
445
                    adr_16_beat={pmi_address[Aw+1 :6], {pmi_address[5:1] + 1'b1},1'b0};
446
                  end else begin
447
                    //pmi_address_nxt_linear_incr = {(pmi_address[Aw+1:2] + 1'b1), 2'b00};
448
                    adr_linear_incr= {(pmi_address[Aw+1:2] + 1'b1), 2'b00};
449
                    adr_4_beat= {pmi_address[Aw+1 :4], {pmi_address[3:2] +1'b1},2'b00};
450
                    adr_8_beat= {pmi_address[Aw+1 :5], {pmi_address[4:2] +1'b1},2'b00};
451
                    adr_16_beat={pmi_address[Aw+1 :6], {pmi_address[5:2] +1'b1},2'b00};
452
                  end
453
           end
454
 
455
 
456
 
457
 
458
           always @(*)begin
459
               case(sa_bte_i)
460
                LINEAR:      pmi_address_nxt = adr_linear_incr;
461
                FOUR_BEAT:   pmi_address_nxt = adr_4_beat;
462
                EIGHT_BEAT:  pmi_address_nxt = adr_8_beat;
463
                SIXTEEN_BEAT:pmi_address_nxt = adr_16_beat;
464
           endcase
465
          end
466
 
467
 
468
         /*----------------------------------------------------------------------
469
          Set up outgoing wishbone signals
470
          ----------------------------------------------------------------------*/
471
         always @(*)
472
           begin
473
              if (((state == ST_IDLE) && sa_cyc_i && sa_stb_i && (sa_ack_o == 1'b0))
474
                  || (state == ST_BURST)
475
                  || (state == ST_SUBRD)
476
                  || (state == ST_SUB))
477
                sa_ack_o_nxt = 1'b1;
478
              else
479
                sa_ack_o_nxt = 1'b0;
480
 
481
              sa_dat_o = data;
482
              sa_rty_o = 1'b0;
483
              sa_err_o = 1'b0;
484
           end
485
 
486
         /*----------------------------------------------------------------------
487
          Sequential Logic
488
          ----------------------------------------------------------------------*/
489
         always @(posedge clk)
490
           if (reset)
491
             begin
492
                sa_ack_o <= #`UDLY 1'b0;
493
                sa_dat_i_d <= #`UDLY 0;
494
                sa_sel_i_d <= #`UDLY 0;
495
                state <= #`UDLY ST_IDLE;
496
                pmi_address <= #`UDLY 0;
497
                write_data_d <= #`UDLY 0;
498
                raw_hazard <= #`UDLY 0;
499
             end
500
           else
501
             begin
502
                sa_ack_o <= #`UDLY sa_ack_o_nxt;
503
                sa_dat_i_d <= #`UDLY sa_dat_i;
504
                sa_sel_i_d <= #`UDLY sa_sel_i;
505
                state <= #`UDLY state_nxt;
506
                pmi_address <= #`UDLY pmi_address_nxt;
507
                write_data_d <= #`UDLY write_data;
508
                raw_hazard <= #`UDLY raw_hazard_nxt;
509
             end
510
 
511
 
512
 
513
 
514
 
515
        assign d        = write_data;
516
        assign addr=(write_enable)? write_address : read_address;
517
        assign we       = write_enable;
518
        assign data= q;
519
        assign byteen = ( delayed_write ) ? sa_sel_i_d : sa_sel_i;
520
 
521
 
522
endmodule

powered by: WebSVN 2.1.0

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