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

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [top/] [scr1_dmem_wb.sv] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  yifive Wishbone interface for Data memory                   ////
4
////                                                              ////
5
////  This file is part of the yifive cores project               ////
6
////  http://www.opencores.org/cores/yifive/                      ////
7
////                                                              ////
8
////  Description:                                                ////
9
////     integrated wishbone i/f to data  memory                  ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Dinesh Annayya, dinesha@opencores.org                 ////
16
////                                                              ////
17
////  Revision :                                                  ////
18
////     v0:    June 7, 2021, Dinesh A                            ////
19
////             wishbone integration                             ////
20 21 dinesha
////     v1:    June 9, 2021, Dinesh A                            ////
21
////              On power up, wishbone output are unkown as it   ////
22
////              driven from fifo output. To avoid unknown       ////
23
////              propgation, we are driving 'h0 when fifo empty  ////
24 11 dinesha
////                                                              ////
25
//////////////////////////////////////////////////////////////////////
26
////                                                              ////
27
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
28
////                                                              ////
29
//// This source file may be used and distributed without         ////
30
//// restriction provided that this copyright statement is not    ////
31
//// removed from the file and that any derivative work contains  ////
32
//// the original copyright notice and the associated disclaimer. ////
33
////                                                              ////
34
//// This source file is free software; you can redistribute it   ////
35
//// and/or modify it under the terms of the GNU Lesser General   ////
36
//// Public License as published by the Free Software Foundation; ////
37
//// either version 2.1 of the License, or (at your option) any   ////
38
//// later version.                                               ////
39
////                                                              ////
40
//// This source is distributed in the hope that it will be       ////
41
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
42
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
43
//// PURPOSE.  See the GNU Lesser General Public License for more ////
44
//// details.                                                     ////
45
////                                                              ////
46
//// You should have received a copy of the GNU Lesser General    ////
47
//// Public License along with this source; if not, download it   ////
48
//// from http://www.opencores.org/lgpl.shtml                     ////
49
////                                                              ////
50
//////////////////////////////////////////////////////////////////////
51
//     Orginal owner Details                                      ////
52
//////////////////////////////////////////////////////////////////////
53
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details///
54
/// @file                                         ///
55
/// @brief      Data memory WB bridge                              ///
56
/////////////////////////////////////////////////////////////////////
57
 
58
`include "scr1_wb.svh"
59
`include "scr1_memif.svh"
60
 
61
module scr1_dmem_wb (
62
    // Control Signals
63
    input   logic                           rst_n,
64
    input   logic                           clk,
65
 
66
    // Core Interface
67
    output  logic                           dmem_req_ack,
68
    input   logic                           dmem_req,
69 21 dinesha
    input   logic                           dmem_cmd,
70
    input   logic [1:0]                     dmem_width,
71 11 dinesha
    input   logic   [SCR1_WB_WIDTH-1:0]     dmem_addr,
72
    input   logic   [SCR1_WB_WIDTH-1:0]     dmem_wdata,
73
    output  logic   [SCR1_WB_WIDTH-1:0]     dmem_rdata,
74 21 dinesha
    output  logic [1:0]                     dmem_resp,
75 11 dinesha
 
76
    // WB Interface
77
    output  logic                           wbd_stb_o, // strobe/request
78
    output  logic   [SCR1_WB_WIDTH-1:0]     wbd_adr_o, // address
79
    output  logic                           wbd_we_o,  // write
80
    output  logic   [SCR1_WB_WIDTH-1:0]     wbd_dat_o, // data output
81
    output  logic   [3:0]                   wbd_sel_o, // byte enable
82
    input   logic   [SCR1_WB_WIDTH-1:0]     wbd_dat_i, // data input
83
    input   logic                           wbd_ack_i, // acknowlegement
84
    input   logic                           wbd_err_i  // error
85
 
86
);
87
 
88
//-------------------------------------------------------------------------------
89
// Local Parameters
90
//-------------------------------------------------------------------------------
91
`ifndef SCR1_DMEM_WB_OUT_BP
92
localparam  SCR1_FIFO_WIDTH = 2;
93
localparam  SCR1_FIFO_CNT_WIDTH = 2;
94
`endif // SCR1_DMEM_WB_OUT_BP
95
 
96
//-------------------------------------------------------------------------------
97
// Local type declaration
98
//-------------------------------------------------------------------------------
99
typedef enum logic {
100
    SCR1_FSM_ADDR = 1'b0,
101
    SCR1_FSM_DATA = 1'b1,
102
    SCR1_FSM_ERR  = 1'bx
103
} type_scr1_fsm_e;
104
 
105
typedef struct packed {
106
    logic                           hwrite;
107
    logic   [2:0]                   hwidth;
108
    logic   [SCR1_WB_WIDTH-1:0]     haddr;
109
    logic   [SCR1_WB_WIDTH-1:0]     hwdata;
110
} type_scr1_req_fifo_s;
111
 
112
typedef struct packed {
113
    logic   [2:0]                   hwidth;
114
    logic   [1:0]                   haddr;
115
} type_scr1_data_fifo_s;
116
 
117
typedef struct packed {
118
    logic                           hresp;
119
    logic   [2:0]                   hwidth;
120
    logic   [1:0]                   haddr;
121
    logic   [SCR1_WB_WIDTH-1:0]    hrdata;
122
} type_scr1_resp_fifo_s;
123
 
124
//-------------------------------------------------------------------------------
125
// Local functions
126
//-------------------------------------------------------------------------------
127
function automatic logic   [2:0] scr1_conv_mem2wb_width (
128 21 dinesha
    input   logic [1:0]              dmem_width
129 11 dinesha
);
130
    logic   [2:0]   tmp;
131
begin
132
    case (dmem_width)
133
        SCR1_MEM_WIDTH_BYTE : begin
134
            tmp = SCR1_DSIZE_8B;
135
        end
136
        SCR1_MEM_WIDTH_HWORD : begin
137
            tmp = SCR1_DSIZE_16B;
138
        end
139
        SCR1_MEM_WIDTH_WORD : begin
140
            tmp = SCR1_DSIZE_32B;
141
        end
142
        default : begin
143
            tmp = SCR1_DSIZE_32B;
144
        end
145
    endcase
146
    scr1_conv_mem2wb_width =  tmp; // cp.11
147
end
148
endfunction
149
 
150
function automatic logic[SCR1_WB_WIDTH-1:0] scr1_conv_mem2wb_wdata (
151
    input   logic   [1:0]                   dmem_addr,
152 21 dinesha
    input   logic [1:0]                     dmem_width,
153 11 dinesha
    input   logic   [SCR1_WB_WIDTH-1:0]    dmem_wdata
154
);
155
    logic   [SCR1_WB_WIDTH-1:0]  tmp;
156
begin
157
    tmp = 'x;
158
    case (dmem_width)
159
        SCR1_MEM_WIDTH_BYTE : begin
160
            case (dmem_addr)
161
                2'b00 : begin
162
                    tmp[7:0]   = dmem_wdata[7:0];
163
                end
164
                2'b01 : begin
165
                    tmp[15:8]  = dmem_wdata[7:0];
166
                end
167
                2'b10 : begin
168
                    tmp[23:16] = dmem_wdata[7:0];
169
                end
170
                2'b11 : begin
171
                    tmp[31:24] = dmem_wdata[7:0];
172
                end
173
                default : begin
174
                end
175
            endcase
176
        end
177
        SCR1_MEM_WIDTH_HWORD : begin
178
            case (dmem_addr[1])
179
                1'b0 : begin
180
                    tmp[15:0]  = dmem_wdata[15:0];
181
                end
182
                1'b1 : begin
183
                    tmp[31:16] = dmem_wdata[15:0];
184
                end
185
                default : begin
186
                end
187
            endcase
188
        end
189
        SCR1_MEM_WIDTH_WORD : begin
190
            tmp = dmem_wdata;
191
        end
192
        default : begin
193
        end
194
    endcase
195
    scr1_conv_mem2wb_wdata = tmp;
196
end
197
endfunction
198
 
199
function automatic logic[SCR1_WB_WIDTH-1:0] scr1_conv_wb2mem_rdata (
200
    input   logic [2:0]                 hwidth,
201
    input   logic [1:0]                 haddr,
202
    input   logic [SCR1_WB_WIDTH-1:0]  hrdata
203
);
204
    logic   [SCR1_WB_WIDTH-1:0]  tmp;
205
begin
206
    tmp = 'x;
207
    case (hwidth)
208
        SCR1_DSIZE_8B : begin
209
            case (haddr)
210
                2'b00 : tmp[7:0] = hrdata[7:0];
211
                2'b01 : tmp[7:0] = hrdata[15:8];
212
                2'b10 : tmp[7:0] = hrdata[23:16];
213
                2'b11 : tmp[7:0] = hrdata[31:24];
214
                default : begin
215
                end
216
            endcase
217
        end
218
        SCR1_DSIZE_16B : begin
219
            case (haddr[1])
220
                1'b0 : tmp[15:0] = hrdata[15:0];
221
                1'b1 : tmp[15:0] = hrdata[31:16];
222
                default : begin
223
                end
224
            endcase
225
        end
226
        SCR1_DSIZE_32B : begin
227
            tmp = hrdata;
228
        end
229
        default : begin
230
        end
231
    endcase
232
    scr1_conv_wb2mem_rdata = tmp;
233
end
234
endfunction
235
 
236
//-------------------------------------------------------------------------------
237
// Local signal declaration
238
//-------------------------------------------------------------------------------
239
logic                                       req_fifo_rd;
240
logic                                       req_fifo_wr;
241
logic                                       req_fifo_up;
242
`ifdef SCR1_DMEM_WB_OUT_BP
243
type_scr1_req_fifo_s                        req_fifo_new;
244
type_scr1_req_fifo_s                        req_fifo_r;
245
type_scr1_req_fifo_s [0:0]                  req_fifo;
246
`else // SCR1_DMEM_WB_OUT_BP
247
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo;
248
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo_new;
249
logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt;
250
logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt_new;
251
`endif // SCR1_DMEM_WB_OUT_BP
252
logic                                       req_fifo_empty;
253
logic                                       req_fifo_full;
254
 
255
type_scr1_data_fifo_s                       data_fifo;
256
type_scr1_resp_fifo_s                       resp_fifo;
257
logic                                       resp_fifo_hready;
258
 
259
//-------------------------------------------------------------------------------
260
// Interface to Core
261
//-------------------------------------------------------------------------------
262
assign dmem_req_ack = ~req_fifo_full;
263
assign req_fifo_wr  = ~req_fifo_full & dmem_req;
264
 
265 21 dinesha
assign dmem_rdata = (resp_fifo_hready) ? scr1_conv_wb2mem_rdata(resp_fifo.hwidth, resp_fifo.haddr, resp_fifo.hrdata) : 'h0;
266 11 dinesha
 
267
assign dmem_resp = (resp_fifo_hready)
268
                    ? (resp_fifo.hresp == 1'b1)
269
                        ? SCR1_MEM_RESP_RDY_OK
270
                        : SCR1_MEM_RESP_RDY_ER
271
                    : SCR1_MEM_RESP_NOTRDY ;
272
 
273
//-------------------------------------------------------------------------------
274
// REQ_FIFO
275
//-------------------------------------------------------------------------------
276
`ifdef SCR1_DMEM_WB_OUT_BP
277
always_ff @(negedge rst_n, posedge clk) begin
278
    if (~rst_n) begin
279
        req_fifo_full <= 1'b0;
280
    end else begin
281
        if (~req_fifo_full) begin
282
            req_fifo_full <= dmem_req & ~req_fifo_rd;
283
        end else begin
284
            req_fifo_full <= ~req_fifo_rd;
285
        end
286
    end
287
end
288
assign req_fifo_empty = ~(req_fifo_full | dmem_req);
289
 
290
assign req_fifo_up = ~req_fifo_rd & req_fifo_wr;
291
always_ff @(posedge clk) begin
292
    if (req_fifo_up) begin
293
        req_fifo_r <= req_fifo_new;
294
    end
295
end
296
 
297
assign req_fifo_new.hwrite = dmem_req ? (dmem_cmd == SCR1_MEM_CMD_WR)       : 1'b0;
298
assign req_fifo_new.hwidth = dmem_req ? scr1_conv_mem2wb_width(dmem_width) : '0;
299
assign req_fifo_new.haddr  = dmem_req ? dmem_addr                           : '0;
300
assign req_fifo_new.hwdata = (dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR))
301
                                ? scr1_conv_mem2wb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata)
302
                                : '0;
303
assign req_fifo[0] = (req_fifo_full) ? req_fifo_r: req_fifo_new;
304
 
305
//-------------------------------------------------------------------------------
306
// Register Data from response path - Used by Read path logic
307
//-------------------------------------------------------------------------------
308
always_ff @(posedge clk) begin
309
    if (wbd_ack_i) begin
310
         if (~req_fifo_empty) begin
311
             data_fifo.hwidth <= req_fifo[0].hwidth;
312
             data_fifo.haddr  <= req_fifo[0].haddr[1:0];
313
         end
314
    end
315
end
316
 
317
`else // SCR1_DMEM_WB_OUT_BP
318
 
319
 
320
wire                     hwrite_in = (dmem_cmd == SCR1_MEM_CMD_WR);
321
wire [2:0]               hwidth_in = scr1_conv_mem2wb_width(dmem_width);
322
wire [SCR1_WB_WIDTH-1:0] haddr_in  = dmem_addr;
323
wire [SCR1_WB_WIDTH-1:0] hwdata_in = scr1_conv_mem2wb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata);
324
 
325
reg  [3:0]              hbel_in; // byte select
326
always_comb begin
327
        hbel_in = 0;
328
    case (hwidth_in)
329
        SCR1_DSIZE_8B : begin
330
            hbel_in = 4'b0001 << haddr_in[1:0];
331
        end
332
        SCR1_DSIZE_16B : begin
333
            hbel_in = 4'b0011 << haddr_in[1:0];
334
        end
335
        SCR1_DSIZE_32B : begin
336
            hbel_in = 4'b1111;
337
        end
338
    endcase
339
end
340
 
341
 
342
wire [SCR1_WB_WIDTH+SCR1_WB_WIDTH+3+4:0] req_fifo_din = {hbel_in,hwrite_in,hwidth_in,haddr_in,hwdata_in};
343 20 dinesha
wire [SCR1_WB_WIDTH+SCR1_WB_WIDTH+3+4:0] req_fifo_dout;
344 11 dinesha
 
345
 sync_fifo #(
346 19 dinesha
      .W(SCR1_WB_WIDTH+SCR1_WB_WIDTH+3+1+4), // Data Width
347
      .D(2)    // FIFO DEPTH
348 11 dinesha
     )   u_req_fifo(
349
 
350 19 dinesha
       .rd_data      (req_fifo_dout  ),
351 11 dinesha
 
352 19 dinesha
       .reset_n   (rst_n          ),
353 11 dinesha
       .clk       (clk            ),
354
       .wr_en     (req_fifo_wr    ), // Write
355
       .rd_en     (req_fifo_rd    ), // Read
356 19 dinesha
       .wr_data   (req_fifo_din   ),
357 11 dinesha
       .full      (req_fifo_full  ),
358
       .empty     (req_fifo_empty )
359
);
360
 
361
//-------------------------------------------------------------------------------
362
// Register Data from response path - Used by Read path logic
363
//-------------------------------------------------------------------------------
364
wire                     hwrite_out;
365
wire [2:0]               hwidth_out;
366
wire [SCR1_WB_WIDTH-1:0] haddr_out;
367
wire [SCR1_WB_WIDTH-1:0] hwdata_out;
368
wire [3:0]               hbel_out;
369
 
370 20 dinesha
 
371 11 dinesha
assign {hbel_out,hwrite_out,hwidth_out,haddr_out,hwdata_out} = req_fifo_dout;
372
 
373
always_ff @(posedge clk) begin
374
    if (wbd_ack_i) begin
375
         if (~req_fifo_empty) begin
376
             data_fifo.hwidth <= hwidth_out;
377
             data_fifo.haddr  <= haddr_out[1:0];
378
         end
379
    end
380
end
381
 
382
`endif // SCR1_DMEM_WB_OUT_BP
383
 
384
 
385
always_comb begin
386
    req_fifo_rd = 1'b0;
387
    if (wbd_ack_i) begin
388
         req_fifo_rd = ~req_fifo_empty;
389
    end
390
end
391
 
392
 
393
//-------------------------------------------------------------------------------
394
// FIFO response
395
//-------------------------------------------------------------------------------
396
`ifdef SCR1_DMEM_WB_IN_BP
397
 
398
assign resp_fifo_hready = wbd_ack_i;
399
assign resp_fifo.hresp  = (wbd_err_i) ? 1'b0 : 1'b1;
400
assign resp_fifo.hwidth = data_fifo.hwidth;
401
assign resp_fifo.haddr  = data_fifo.haddr;
402
assign resp_fifo.hrdata = wbd_dat_i;
403
 
404
assign wbd_stb_o     = ~req_fifo_empty;
405
assign wbd_adr_o    = req_fifo[0].haddr;
406
assign wbd_we_o     = req_fifo[0].hwrite;
407
assign wbd_dat_o    = req_fifo[0].hwdata;
408
 
409
always_comb begin
410
        wbd_sel_o = 0;
411
    case (req_fifo[0].hwidth)
412
        SCR1_DSIZE_8B : begin
413
            wbd_sel_o = 4'b0001 << req_fifo[0].haddr[1:0];
414
        end
415
        SCR1_DSIZE_16B : begin
416
            wbd_sel_o = 4'b0011 << req_fifo[0].haddr[1:0];
417
        end
418
        SCR1_DSIZE_32B : begin
419
            wbd_sel_o = 4'b1111;
420
        end
421
    endcase
422
end
423
`else // SCR1_DMEM_WB_IN_BP
424
always_ff @(negedge rst_n, posedge clk) begin
425
    if (~rst_n) begin
426
        resp_fifo_hready <= 1'b0;
427
    end else begin
428
        resp_fifo_hready <= wbd_ack_i ;
429
    end
430
end
431
 
432
always_ff @(posedge clk) begin
433
    if (wbd_ack_i) begin
434
        resp_fifo.hresp  <= (wbd_err_i) ? 1'b0 : 1'b1;
435 21 dinesha
        resp_fifo.hwidth <= hwidth_out;
436
        resp_fifo.haddr  <= haddr_out[1:0];
437
        resp_fifo.hrdata <= (wbd_we_o) ? 'h0: wbd_dat_i;
438 11 dinesha
    end
439
end
440
 
441
 
442
assign wbd_stb_o    = ~req_fifo_empty;
443
 
444 21 dinesha
// To avoid unknown progating the design, driven zero when fifo is empty
445
assign wbd_adr_o    = (req_fifo_empty) ? 'h0 : haddr_out;
446
assign wbd_we_o     = (req_fifo_empty) ? 'h0 : hwrite_out;
447
assign wbd_dat_o    = (req_fifo_empty) ? 'h0 : hwdata_out;
448
assign wbd_sel_o    = (req_fifo_empty) ? 'h0 : hbel_out;
449
 
450 11 dinesha
`endif // SCR1_DMEM_WB_IN_BP
451
 
452
 
453
 
454
endmodule : scr1_dmem_wb

powered by: WebSVN 2.1.0

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