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 11

Go to most recent revision | 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
    input   type_scr1_mem_cmd_e             core_cmd,
27
    input   type_scr1_mem_width_e           core_width,
28
    input   logic [SCR1_ADDR_WIDTH-1:0]     core_addr,
29
    input   logic [31:0]                    core_wdata,
30
    output  logic [31:0]                    core_rdata,
31
    output  type_scr1_mem_resp_e            core_resp,
32
 
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
    input   type_scr1_mem_width_e    width );
84
    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
    type_scr1_mem_width_e                               axi_width;
99
    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
type_scr1_mem_resp_e                                    rcvd_resp;
133
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
 
312
// Read data adaptation
313
always_comb begin
314
   case (req_fifo_axi_width[req_done_ptr])
315
        SCR1_MEM_WIDTH_BYTE :  rcvd_rdata = rdata >> (8*bShift2);
316
        SCR1_MEM_WIDTH_HWORD:  rcvd_rdata = rdata >> (8*bShift2);
317
        SCR1_MEM_WIDTH_WORD :  rcvd_rdata = rdata >> (8*bShift2);
318
        default:  rcvd_rdata = 'x;
319
    endcase
320
end
321
 
322
 
323
generate
324
    if (SCR1_AXI_RESP_BP == 1) begin : axi_resp_bp
325
        assign core_rdata = (rvalid & rready & rlast) ? rcvd_rdata : '0;
326
        assign core_resp  = (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
327
    end else begin : axi_resp_no_bp
328
        always_ff @(negedge rst_n, posedge clk) begin
329
            if (~rst_n)              core_resp  <= SCR1_MEM_RESP_NOTRDY;
330
            else                     core_resp  <= (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
331
        end
332
        always_ff @(posedge clk) begin
333
            if (rvalid & rready & rlast) core_rdata <= rcvd_rdata;
334
        end
335
    end
336
endgenerate
337
 
338
 
339
 
340
// AXI interface assignments
341
assign awid     = SCR1_AXI_IDWIDTH'(1);
342
assign awlen    = 8'd0;
343
assign awsize   = (force_write) ? width2axsize(core_width) : width2axsize(req_fifo_axi_width[req_proc_ptr]);
344
assign awburst  = 2'd1;
345
assign awcache  = 4'd2;
346
assign awlock   = '0;
347
assign awprot   = '0;
348
assign awregion = '0;
349
assign awuser   = '0;
350
assign awqos    = '0;
351
 
352
assign arid     = SCR1_AXI_IDWIDTH'(0);
353
assign arlen    = 8'd0;
354
assign arsize   = (force_read) ? width2axsize(core_width) : width2axsize(req_fifo_axi_width[req_proc_ptr]);
355
assign arburst  = 2'd1;
356
assign arcache  = 4'd2;
357
assign arprot   = '0;
358
assign arregion = '0;
359
assign arlock   = '0;
360
assign arqos    = '0;
361
assign aruser   = '0;
362
 
363
assign wlast    = 1'd1;
364
assign wuser    = '0;
365
 
366
 
367
`ifdef SCR1_TRGT_SIMULATION
368
//-------------------------------------------------------------------------------
369
// Assertion
370
//-------------------------------------------------------------------------------
371
 
372
// X checks
373
SCR1_SVA_AXI_X_CHECK0  : assert property (@(negedge clk) disable iff (~rst_n)   !$isunknown({core_req, awready, wready, bvalid, arready, rvalid}) )
374
                                                                                                        else $error("AXI bridge: X state on input");
375
SCR1_SVA_AXI_X_CHECK1  : assert property (@(negedge clk) disable iff (~rst_n)   core_req |->
376
                                                                                    !$isunknown({core_cmd, core_width, core_addr}) )
377
                                                                                                        else $error("AXI bridge: X state on input");
378
SCR1_SVA_AXI_X_CHECK2  : assert property (@(negedge clk) disable iff (~rst_n)   bvalid |->
379
                                                                                    !$isunknown({bid, bresp}) )
380
                                                                                                        else $error("AXI bridge: X state on input");
381
SCR1_SVA_AXI_X_CHECK3  : assert property (@(negedge clk) disable iff (~rst_n)   rvalid |->
382
                                                                                    !$isunknown({rid, rresp}) )
383
                                                                                                        else $error("AXI bridge: X state on input");
384
`endif // SCR1_TRGT_SIMULATION
385
 
386
endmodule : scr1_mem_axi

powered by: WebSVN 2.1.0

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