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/] [src_c/] [jtag/] [test_rtl/] [jtag_ram_test/] [src_verilog/] [lib/] [wb_bram_ctrl.v] - Blame information for rev 38

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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