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

Subversion Repositories yifive

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 dinesha
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
2
/// @file       
3
/// @brief      Memory AXI bridge
4
///
5
 
6
`include "scr1_memif.svh"
7
`include "scr1_arch_description.svh"
8
 
9
module scr1_mem_axi
10
#(
11
    parameter SCR1_REQ_BUF_SIZE     = 2,                    // Power of 2 value
12
    parameter SCR1_AXI_IDWIDTH      = 4,
13
    parameter SCR1_ADDR_WIDTH       = 32,
14
    parameter SCR1_AXI_REQ_BP       = 1,
15
    parameter SCR1_AXI_RESP_BP      = 1
16
)
17
(
18
    // Clock and Reset
19
    input   logic                           clk,
20
    input   logic                           rst_n,
21
    input   logic                           axi_reinit,
22
    // Core Interface
23
    output  logic                           core_idle,
24
    output  logic                           core_req_ack,
25
    input   logic                           core_req,
26 21 dinesha
    input   logic                           core_cmd,
27
    input   logic [1:0]                     core_width,
28 11 dinesha
    input   logic [SCR1_ADDR_WIDTH-1:0]     core_addr,
29
    input   logic [31:0]                    core_wdata,
30
    output  logic [31:0]                    core_rdata,
31 21 dinesha
    output  logic [1:0]                     core_resp,
32 11 dinesha
 
33
    // AXI
34
    output  logic [SCR1_AXI_IDWIDTH-1:0]    awid,
35
    output  logic [SCR1_ADDR_WIDTH-1:0]     awaddr,
36
    output  logic [ 7:0]                    awlen,
37
    output  logic [ 2:0]                    awsize,
38
    output  logic [ 1:0]                    awburst,
39
    output  logic                           awlock,
40
    output  logic [ 3:0]                    awcache,
41
    output  logic [ 2:0]                    awprot,
42
    output  logic [ 3:0]                    awregion,
43
    output  logic [ 3:0]                    awuser,
44
    output  logic [ 3:0]                    awqos,
45
    output  logic                           awvalid,
46
    input   logic                           awready,
47
    output  logic [31:0]                    wdata,
48
    output  logic [3:0]                     wstrb,
49
    output  logic                           wlast,
50
    output  logic [3:0]                     wuser,
51
    output  logic                           wvalid,
52
    input   logic                           wready,
53
    input   logic [SCR1_AXI_IDWIDTH-1:0]    bid,
54
    input   logic [ 1:0]                    bresp,
55
    input   logic                           bvalid,
56
    input   logic [ 3:0]                    buser,
57
    output  logic                           bready,
58
    output  logic [SCR1_AXI_IDWIDTH-1:0]    arid,
59
    output  logic [SCR1_ADDR_WIDTH-1:0]     araddr,
60
    output  logic [ 7:0]                    arlen,
61
    output  logic [ 2:0]                    arsize,
62
    output  logic [ 1:0]                    arburst,
63
    output  logic                           arlock,
64
    output  logic [ 3:0]                    arcache,
65
    output  logic [ 2:0]                    arprot,
66
    output  logic [ 3:0]                    arregion,
67
    output  logic [ 3:0]                    aruser,
68
    output  logic [ 3:0]                    arqos,
69
    output  logic                           arvalid,
70
    input   logic                           arready,
71
    input   logic [SCR1_AXI_IDWIDTH-1:0]    rid,
72
    input   logic [31:0]                    rdata,
73
    input   logic [ 1:0]                    rresp,
74
    input   logic                           rlast,
75
    input   logic [ 3:0]                    ruser,
76
    input   logic                           rvalid,
77
    output  logic                           rready
78
);
79
 
80
 
81
// Local functions
82
function automatic logic [2:0] width2axsize (
83 21 dinesha
    input   logic [1:0]              width );
84 11 dinesha
    logic [2:0] axsize;
85
begin
86
    case (width)
87
        SCR1_MEM_WIDTH_BYTE :  axsize = 3'b000;
88
        SCR1_MEM_WIDTH_HWORD:  axsize = 3'b001;
89
        SCR1_MEM_WIDTH_WORD :  axsize = 3'b010;
90
                     default:  axsize = 'x;
91
    endcase
92
 
93
    width2axsize = axsize; // cp.11
94
end
95
endfunction
96
 
97
typedef struct packed {
98 21 dinesha
    logic [1:0]                                         axi_width;
99 11 dinesha
    logic                    [SCR1_ADDR_WIDTH-1:0]      axi_addr;
100
    logic                                   [31:0]      axi_wdata;
101
} type_scr1_request_s;
102
 
103
typedef struct packed {
104
    logic                                               req_write;
105
    logic                                               req_addr;
106
    logic                                               req_data;
107
    logic                                               req_resp;
108
} type_scr1_req_status_s;
109
 
110
 
111
//type_scr1_request_s         [SCR1_REQ_BUF_SIZE-1:0]   req_fifo;
112
logic [1:0]                                             req_fifo_axi_width[SCR1_REQ_BUF_SIZE-1:0];
113
logic [SCR1_ADDR_WIDTH-1:0]                             req_fifo_axi_addr [SCR1_REQ_BUF_SIZE-1:0];
114
logic [31:0]                                            req_fifo_axi_wdata [SCR1_REQ_BUF_SIZE-1:0];
115
//type_scr1_req_status_s      [SCR1_REQ_BUF_SIZE-1:0]   req_status;
116
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_req_write ;
117
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_req_addr ;
118
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_req_data ;
119
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_req_resp ;
120
//type_scr1_req_status_s      [SCR1_REQ_BUF_SIZE-1:0]   req_status_new;
121
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_new_req_write ;
122
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_new_req_addr ;
123
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_new_req_data ;
124
logic   [SCR1_REQ_BUF_SIZE-1:0]                         req_status_new_req_resp ;
125
 
126
logic                       [SCR1_REQ_BUF_SIZE-1:0]     req_status_en;
127
logic               [$clog2(SCR1_REQ_BUF_SIZE)-1:0]     req_aval_ptr;
128
logic               [$clog2(SCR1_REQ_BUF_SIZE)-1:0]     req_proc_ptr;
129
logic               [$clog2(SCR1_REQ_BUF_SIZE)-1:0]     req_done_ptr;
130
logic                                                   rresp_err;
131
logic                                       [31:0]      rcvd_rdata;
132 21 dinesha
logic [1:0]                                             rcvd_resp;
133 11 dinesha
logic                                                   force_read;
134
logic                                                   force_write;
135
 
136
 
137
 
138
assign core_req_ack =   ~axi_reinit                        &
139
                        ~req_status_req_resp[req_aval_ptr] &
140
                         core_resp!=SCR1_MEM_RESP_RDY_ER;
141
 
142
 
143
assign rready      = ~req_status_req_write[req_done_ptr];
144
assign bready      =  req_status_req_write[req_done_ptr];
145
 
146
 
147
assign force_read  = SCR1_AXI_REQ_BP & core_req & core_req_ack & req_aval_ptr==req_proc_ptr & core_cmd==SCR1_MEM_CMD_RD;
148
assign force_write = SCR1_AXI_REQ_BP & core_req & core_req_ack & req_aval_ptr==req_proc_ptr & core_cmd==SCR1_MEM_CMD_WR;
149
 
150
integer i;
151
always_comb begin: idle_status
152
    core_idle = 1'b1;
153
    for (i=0; i
154
        core_idle &= req_status_req_resp[i]==1'b0;
155
    end
156
end
157
 
158
always_ff @(posedge clk) begin
159
    if (core_req & core_req_ack) begin
160
        req_fifo_axi_width[req_aval_ptr] <= core_width;
161
        req_fifo_axi_addr[req_aval_ptr]  <= core_addr;
162
        req_fifo_axi_wdata[req_aval_ptr] <= core_wdata;
163
    end
164
end
165
 
166
// Request Status Queue
167
// It is used for holding control info of processing requests
168
 
169
// Combinational logic of Request Status Queue
170
always_comb begin
171
    // Default
172
    req_status_en  = '0; // No update
173
    req_status_new_req_write = req_status_req_write; // Hold request info
174
    req_status_new_req_addr  = req_status_req_addr; // Hold request info
175
    req_status_new_req_data  = req_status_req_data; // Hold request info
176
    req_status_new_req_resp  = req_status_req_resp; // Hold request info
177
 
178
    // Update status on new core request
179
    if( core_req & core_req_ack ) begin
180
        req_status_en[req_aval_ptr]            = 1'd1;
181
 
182
        req_status_new_req_resp[req_aval_ptr]  = 1'd1;
183
        req_status_new_req_write[req_aval_ptr] = core_cmd == SCR1_MEM_CMD_WR;
184
 
185
        req_status_new_req_addr[req_aval_ptr]  = ~( (force_read & arready) |
186
                                                    (force_write & awready) );
187
 
188
        req_status_new_req_data[req_aval_ptr]  = ~( (force_write & wready & awlen == 8'd0) |
189
                                                    (~force_write & core_cmd == SCR1_MEM_CMD_RD) );
190
    end
191
 
192
    // Update status on AXI address phase
193
    if ( (awvalid & awready) | (arvalid & arready) ) begin
194
        req_status_en[req_proc_ptr]           = 1'd1;
195
        req_status_new_req_addr[req_proc_ptr] = 1'd0;
196
    end
197
 
198
    // Update status on AXI data phase
199
    if ( wvalid & wready & wlast ) begin
200
        req_status_en[req_proc_ptr]           = 1'd1;
201
        req_status_new_req_data[req_proc_ptr] = 1'd0;
202
    end
203
 
204
    // Update status when AXI finish transaction
205
    if ( (bvalid & bready) | (rvalid & rready & rlast) ) begin
206
        req_status_en[req_done_ptr]           = 1'd1;
207
        req_status_new_req_resp[req_done_ptr] = 1'd0;
208
    end
209
end
210
 
211
// Request Status Queue register
212
integer j;
213
always_ff @(negedge rst_n, posedge clk) begin
214
    if (~rst_n) begin
215
        req_status_req_write <= '0;
216
        req_status_req_addr <= '0;
217
        req_status_req_data <= '0;
218
        req_status_req_resp <= '0;
219
    end else begin
220
        for (j = 0; j < SCR1_REQ_BUF_SIZE; j = j+1) begin // cp.4
221
            if ( req_status_en[j] ) begin
222
                req_status_req_write[j] <= req_status_new_req_write[j];
223
                req_status_req_addr[j]  <= req_status_new_req_addr[j];
224
                req_status_req_data[j]  <= req_status_new_req_data[j];
225
                req_status_req_resp[j]  <= req_status_new_req_resp[j];
226
            end
227
        end
228
    end
229
end
230
 
231
always_ff @(negedge rst_n, posedge clk) begin
232
    if (~rst_n)                         req_aval_ptr <= '0;
233
    else if (core_req & core_req_ack)   req_aval_ptr <= req_aval_ptr + 1'b1;
234
end
235
 
236
always_ff @(negedge rst_n, posedge clk) begin
237
    if (~rst_n) begin
238
        req_proc_ptr <= '0;
239
    end else begin
240
        if ((                                                    awvalid & awready & wvalid & wready & wlast) |
241
            (~force_write & ~req_status_req_data[req_proc_ptr] & awvalid & awready                          ) |
242
            (~force_write & ~req_status_req_addr[req_proc_ptr] &                     wvalid & wready & wlast) |
243
            (               ~req_status_req_data[req_proc_ptr] & arvalid & arready                          )  ) begin
244
 
245
            req_proc_ptr <= req_proc_ptr + 1'b1;
246
        end
247
    end
248
end
249
 
250
always_ff @(negedge rst_n, posedge clk) begin
251
    if (~rst_n) begin
252
        req_done_ptr <= '0;
253
    end else begin
254
        if ((bvalid & bready | rvalid & rready & rlast) & req_status_req_resp[req_done_ptr]) begin
255
 
256
            req_done_ptr <= req_done_ptr + 1'b1;
257
        end
258
    end
259
end
260
 
261
 
262
 
263
assign arvalid = req_status_req_addr[req_proc_ptr] & ~req_status_req_write[req_proc_ptr] | force_read;
264
assign awvalid = req_status_req_addr[req_proc_ptr] &  req_status_req_write[req_proc_ptr] | force_write;
265
assign  wvalid = req_status_req_data[req_proc_ptr] &  req_status_req_write[req_proc_ptr] | force_write;
266
 
267
assign araddr  = (~force_read )? req_fifo_axi_addr[req_proc_ptr] : core_addr;
268
assign awaddr  = (~force_write)? req_fifo_axi_addr[req_proc_ptr] : core_addr;
269
 
270
always_comb begin
271
    if (bvalid & bready & req_status_req_resp[req_done_ptr]) begin
272
        rcvd_resp = (bresp==2'b00)? SCR1_MEM_RESP_RDY_OK :
273
                                    SCR1_MEM_RESP_RDY_ER;
274
    end else begin
275
        if (rvalid & rready & rlast & req_status_req_resp[req_done_ptr]) begin
276
            rcvd_resp = (rresp==2'b00)? SCR1_MEM_RESP_RDY_OK :
277
                                        SCR1_MEM_RESP_RDY_ER;
278
        end else begin
279
            rcvd_resp = SCR1_MEM_RESP_NOTRDY;
280
        end
281
    end
282
end
283
 
284
 
285
wire [SCR1_ADDR_WIDTH-1:0] CurAddr1 = req_fifo_axi_addr[req_proc_ptr];
286
wire [1:0]  bShift1 = CurAddr1[1:0];
287
 
288
// Write data signals adaptation
289
always_comb begin
290
    if (force_write)
291
        case (core_width)
292
            SCR1_MEM_WIDTH_BYTE :  wstrb = 4'h1 << core_addr[1:0];
293
            SCR1_MEM_WIDTH_HWORD:  wstrb = 4'h3 << core_addr[1:0];
294
            SCR1_MEM_WIDTH_WORD :  wstrb = 4'hf << core_addr[1:0];
295
                         default:  wstrb = 'x;
296
        endcase
297
    else
298
        case (req_fifo_axi_width[req_proc_ptr])
299
            SCR1_MEM_WIDTH_BYTE :  wstrb = 4'h1 << bShift1;
300
            SCR1_MEM_WIDTH_HWORD:  wstrb = 4'h3 << bShift1;
301
            SCR1_MEM_WIDTH_WORD :  wstrb = 4'hf << bShift1;
302
                         default:  wstrb = 'x;
303
        endcase
304
end
305
 
306
 
307
 
308
assign wdata = (force_write)?                       core_wdata << (8*                       core_addr[1:0]) :
309
                              req_fifo_axi_wdata[req_proc_ptr] << (8* bShift1);
310
 
311 21 dinesha
wire [SCR1_ADDR_WIDTH-1:0] CurAddr2 = req_fifo_axi_addr[req_done_ptr];
312
wire [1:0]  bShift2 = CurAddr2[1:0];
313 11 dinesha
 
314
// Read data adaptation
315
always_comb begin
316
   case (req_fifo_axi_width[req_done_ptr])
317
        SCR1_MEM_WIDTH_BYTE :  rcvd_rdata = rdata >> (8*bShift2);
318
        SCR1_MEM_WIDTH_HWORD:  rcvd_rdata = rdata >> (8*bShift2);
319
        SCR1_MEM_WIDTH_WORD :  rcvd_rdata = rdata >> (8*bShift2);
320
        default:  rcvd_rdata = 'x;
321
    endcase
322
end
323
 
324
 
325
generate
326
    if (SCR1_AXI_RESP_BP == 1) begin : axi_resp_bp
327
        assign core_rdata = (rvalid & rready & rlast) ? rcvd_rdata : '0;
328
        assign core_resp  = (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
329
    end else begin : axi_resp_no_bp
330
        always_ff @(negedge rst_n, posedge clk) begin
331
            if (~rst_n)              core_resp  <= SCR1_MEM_RESP_NOTRDY;
332
            else                     core_resp  <= (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
333
        end
334
        always_ff @(posedge clk) begin
335
            if (rvalid & rready & rlast) core_rdata <= rcvd_rdata;
336
        end
337
    end
338
endgenerate
339
 
340
 
341
 
342
// AXI interface assignments
343
assign awid     = SCR1_AXI_IDWIDTH'(1);
344
assign awlen    = 8'd0;
345
assign awsize   = (force_write) ? width2axsize(core_width) : width2axsize(req_fifo_axi_width[req_proc_ptr]);
346
assign awburst  = 2'd1;
347
assign awcache  = 4'd2;
348
assign awlock   = '0;
349
assign awprot   = '0;
350
assign awregion = '0;
351
assign awuser   = '0;
352
assign awqos    = '0;
353
 
354
assign arid     = SCR1_AXI_IDWIDTH'(0);
355
assign arlen    = 8'd0;
356
assign arsize   = (force_read) ? width2axsize(core_width) : width2axsize(req_fifo_axi_width[req_proc_ptr]);
357
assign arburst  = 2'd1;
358
assign arcache  = 4'd2;
359
assign arprot   = '0;
360
assign arregion = '0;
361
assign arlock   = '0;
362
assign arqos    = '0;
363
assign aruser   = '0;
364
 
365
assign wlast    = 1'd1;
366
assign wuser    = '0;
367
 
368
 
369
`ifdef SCR1_TRGT_SIMULATION
370
//-------------------------------------------------------------------------------
371
// Assertion
372
//-------------------------------------------------------------------------------
373
 
374
// X checks
375
SCR1_SVA_AXI_X_CHECK0  : assert property (@(negedge clk) disable iff (~rst_n)   !$isunknown({core_req, awready, wready, bvalid, arready, rvalid}) )
376
                                                                                                        else $error("AXI bridge: X state on input");
377
SCR1_SVA_AXI_X_CHECK1  : assert property (@(negedge clk) disable iff (~rst_n)   core_req |->
378
                                                                                    !$isunknown({core_cmd, core_width, core_addr}) )
379
                                                                                                        else $error("AXI bridge: X state on input");
380
SCR1_SVA_AXI_X_CHECK2  : assert property (@(negedge clk) disable iff (~rst_n)   bvalid |->
381
                                                                                    !$isunknown({bid, bresp}) )
382
                                                                                                        else $error("AXI bridge: X state on input");
383
SCR1_SVA_AXI_X_CHECK3  : assert property (@(negedge clk) disable iff (~rst_n)   rvalid |->
384
                                                                                    !$isunknown({rid, rresp}) )
385
                                                                                                        else $error("AXI bridge: X state on input");
386
`endif // SCR1_TRGT_SIMULATION
387
 
388
endmodule : scr1_mem_axi

powered by: WebSVN 2.1.0

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