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 20

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

powered by: WebSVN 2.1.0

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