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

Subversion Repositories spacewiresystemc

[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [altera_merlin_reorder_memory.sv] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 32 redbear
// (C) 2001-2017 Intel Corporation. All rights reserved.
2
// Your use of Intel Corporation's design tools, logic functions and other
3
// software and tools, and its AMPP partner logic functions, and any output
4 40 redbear
// files from any of the foregoing (including device programming or simulation
5 32 redbear
// files), and any associated documentation or information are expressly subject
6
// to the terms and conditions of the Intel Program License Subscription
7 40 redbear
// Agreement, Intel FPGA IP License Agreement, or other applicable
8 32 redbear
// license agreement, including, without limitation, that your use is for the
9
// sole purpose of programming logic devices manufactured by Intel and sold by
10
// Intel or its authorized distributors.  Please refer to the applicable
11
// agreement for further details.
12
 
13
 
14 40 redbear
// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_traffic_limiter/altera_merlin_reorder_memory.sv#1 $
15 32 redbear
// $Revision: #1 $
16 40 redbear
// $Date: 2017/07/30 $
17 32 redbear
// $Author: swbranch $
18
 
19
// ------------------------------------------------------------------
20
// Merlin Order Memory: this stores responses from slave
21
// and do reorder. The memory structure is normal memory
22
// with many segments for different responses that master
23
// can handle.
24
// The number of segment is the number of MAX_OUTSTANDING_RESPONSE
25
// ------------------------------------------------------------------
26
 
27
`timescale 1 ns / 1 ns
28
module altera_merlin_reorder_memory
29
#(
30
   parameter  DATA_W         = 32,
31
              ADDR_H_W       = 4, // width to represent how many segments
32
              ADDR_L_W       = 4,
33
              VALID_W        = 4,
34
              NUM_SEGMENT    = 4,
35
              DEPTH          = 16
36
 
37
)
38
 
39
(
40
    // -------------------
41
    // Clock
42
    // -------------------
43
    input                       clk,
44
    input                       reset,
45
    // -------------------
46
    // Signals
47
    // -------------------
48
    input [DATA_W - 1 : 0]      in_data,
49
    input                       in_valid,
50
    output                      in_ready,
51
 
52
    output reg [DATA_W - 1 : 0] out_data,
53
    output reg                  out_valid,
54
    input                       out_ready,
55
    // --------------------------------------------
56
    // wr_segment: select write portion of memory
57
    // rd_segment: select read portion of memory
58
    // --------------------------------------------
59
    input [ADDR_H_W - 1 : 0]    wr_segment,
60
    input [ADDR_H_W - 1 : 0]    rd_segment
61
 
62
);
63
 
64
    // -------------------------------------
65
    // Local parameter
66
    // -------------------------------------
67
    localparam SEGMENT_W  = ADDR_H_W;
68
 
69
    wire [ADDR_H_W + ADDR_L_W - 1 : 0] mem_wr_addr;
70
    reg [ADDR_H_W + ADDR_L_W - 1 : 0]  mem_rd_addr;
71
    wire [ADDR_L_W - 1 : 0]            mem_wr_ptr;
72
    wire [ADDR_L_W - 1 : 0]            mem_rd_ptr;
73
    reg [ADDR_L_W - 1 : 0]             mem_next_rd_ptr;
74
    reg [DATA_W - 1 : 0]               out_payload;
75
 
76
    wire [NUM_SEGMENT - 1 : 0]         pointer_ctrl_in_ready;
77
    wire [NUM_SEGMENT - 1 : 0]         pointer_ctrl_in_valid;
78
    wire [NUM_SEGMENT - 1 : 0]         pointer_ctrl_out_valid;
79
    wire [NUM_SEGMENT - 1 : 0]         pointer_ctrl_out_ready;
80
    wire [ADDR_L_W - 1 : 0]            pointer_ctrl_wr_ptr [NUM_SEGMENT];
81
    wire [ADDR_L_W - 1 : 0]            pointer_ctrl_rd_ptr [NUM_SEGMENT];
82
    wire [ADDR_L_W - 1 : 0]            pointer_ctrl_next_rd_ptr [NUM_SEGMENT];
83
 
84
    // ---------------------------------
85
    // Memory storage
86
    // ---------------------------------
87
    (* ramstyle="no_rw_check" *) reg [DATA_W - 1 : 0]               mem [DEPTH - 1 : 0];
88
        always @(posedge clk) begin
89
                if (in_valid && in_ready)
90
                        mem[mem_wr_addr] = in_data;
91
        out_payload = mem[mem_rd_addr];
92
        end
93
    //assign mem_rd_addr  = {rd_segment, mem_next_rd_ptr};
94
 
95
    always_comb
96
       begin
97
           out_data  = out_payload;
98
           out_valid = pointer_ctrl_out_valid[rd_segment];
99
       end
100
    // ---------------------------------
101
    // Memory addresses
102
    // ---------------------------------
103
    assign mem_wr_ptr       = pointer_ctrl_wr_ptr[wr_segment];
104
    //assign mem_rd_ptr       = pointer_ctrl_rd_ptr[rd_segment];
105
    //assign mem_next_rd_ptr  = pointer_ctrl_next_rd_ptr[rd_segment];
106
 
107
    assign mem_wr_addr  = {wr_segment, mem_wr_ptr};
108
 
109
    // ---------------------------------------------------------------------------
110
    // Bcos want, empty latency, mean assert read the data will appear on out_data.
111
    // And need to jump around different segment of the memory.
112
    // So when seeing endofpacket for this current segment, the read address
113
    // will jump to next segment at first read address, so that the data will be ready
114
    // it is okay to jump to next segment as this is the sequence of all transaction
115
    // and they just increment. (standing at segment 0, then for sure next segment 1)
116
    // ----------------------------------------------------------------------------
117
    wire endofpacket;
118
    assign endofpacket  = out_payload[0];
119
    wire [ADDR_H_W - 1: 0] next_rd_segment;
120
    assign next_rd_segment  = ((rd_segment + 1'b1) == NUM_SEGMENT) ? '0 : rd_segment + 1'b1;
121
 
122
    always_comb
123
        begin
124
            if (out_valid && out_ready && endofpacket)
125
                begin
126
                    mem_next_rd_ptr  = pointer_ctrl_rd_ptr[next_rd_segment];
127
                    //mem_rd_addr      = {rd_segment + 1'b1, mem_next_rd_ptr};
128
                                        mem_rd_addr      = {next_rd_segment, mem_next_rd_ptr};
129
 
130
                end
131
            else
132
                begin
133
                    mem_next_rd_ptr  = pointer_ctrl_next_rd_ptr[rd_segment];
134
                    mem_rd_addr      = {rd_segment, mem_next_rd_ptr};
135
                end
136
        end
137
 
138
 
139
    // ---------------------------------
140
    // Output signals
141
    // ---------------------------------
142
    assign in_ready  = pointer_ctrl_in_ready[wr_segment];
143
 
144
    // ---------------------------------
145
    // Control signals for each segment
146
    // ---------------------------------
147
    genvar j;
148
    generate
149
        for (j = 0; j < NUM_SEGMENT; j = j + 1)
150
            begin : pointer_signal
151
                assign pointer_ctrl_in_valid[j]  = (wr_segment == j) && in_valid;
152
                assign pointer_ctrl_out_ready[j]  = (rd_segment == j) && out_ready;
153
 
154
            end
155
    endgenerate
156
 
157
    // ---------------------------------
158
    // Seperate write and read pointer
159
    // for each segment in memory
160
    // ---------------------------------
161
    genvar i;
162
    generate
163
        for (i = 0; i < NUM_SEGMENT; i = i + 1)
164
            begin : each_segment_pointer_controller
165
                    memory_pointer_controller
166
                 #(
167
                   .ADDR_W   (ADDR_L_W)
168
                   ) reorder_memory_pointer_controller
169
                 (
170
                  .clk              (clk),
171
                  .reset            (reset),
172
                  .in_ready         (pointer_ctrl_in_ready[i]),
173
                  .in_valid         (pointer_ctrl_in_valid[i]),
174
                  .out_ready        (pointer_ctrl_out_ready[i]),
175
                  .out_valid            (pointer_ctrl_out_valid[i]),
176
                          .wr_pointer           (pointer_ctrl_wr_ptr[i]),
177
                  .rd_pointer       (pointer_ctrl_rd_ptr[i]),
178
                  .next_rd_pointer  (pointer_ctrl_next_rd_ptr[i])
179
                  );
180
            end // block: each_segment_pointer_controller
181
    endgenerate
182
endmodule
183
 
184
 
185
module memory_pointer_controller
186
#(
187
    parameter ADDR_W   = 4
188
)
189
(
190
    // -------------------
191
    // Clock
192
    // -------------------
193
    input                   clk,
194
    input                   reset,
195
    // -------------------
196
    // Signals
197
    // -------------------
198
    output reg              in_ready,
199
        input                   in_valid,
200
    input                   out_ready,
201
    output reg              out_valid,
202
        // -------------------------------
203
    // Output write and read pointer
204
    // -------------------------------
205
        output [ADDR_W - 1 : 0] wr_pointer,
206
        output [ADDR_W - 1 : 0] rd_pointer,
207
    output [ADDR_W - 1 : 0] next_rd_pointer
208
);
209
 
210
        reg [ADDR_W - 1 : 0]            incremented_wr_ptr;
211
        reg [ADDR_W - 1 : 0]            incremented_rd_ptr;
212
        reg [ADDR_W - 1 : 0]            wr_ptr;
213
        reg [ADDR_W - 1 : 0]            rd_ptr;
214
        reg [ADDR_W - 1 : 0]            next_wr_ptr;
215
        reg [ADDR_W - 1 : 0]            next_rd_ptr;
216
        reg full, empty, next_full, next_empty;
217
        reg read, write, internal_out_ready, internal_out_valid;
218
 
219
        assign incremented_wr_ptr = wr_ptr + 1'b1;
220
        assign incremented_rd_ptr = rd_ptr + 1'b1;
221
        assign next_wr_ptr =  write ?  incremented_wr_ptr : wr_ptr;
222
        assign next_rd_ptr = read ? incremented_rd_ptr : rd_ptr;
223
        assign wr_pointer  = wr_ptr;
224
    assign rd_pointer  = rd_ptr;
225
    assign next_rd_pointer  = next_rd_ptr;
226
 
227
        // -------------------------------
228
    // Define write and read signals
229
    // --------------------------------
230
    // internal read, if it has any valid data
231
    // and output are ready to accepts data then a read will be performed.
232
    // -------------------------------
233
        //assign read  = internal_out_ready && internal_out_valid;
234
    assign read  = internal_out_ready && !empty;
235
        assign write = in_ready && in_valid;
236
 
237
        always_ff @(posedge clk or posedge reset)
238
        begin
239
                    if (reset)
240
                begin
241
                                wr_ptr <= 0;
242
                                rd_ptr <= 0;
243
                        end
244
            else
245
                begin
246
                                wr_ptr <= next_wr_ptr;
247
                                rd_ptr <= next_rd_ptr;
248
                        end
249
            end
250
    // ---------------------------------------------------------------------------
251
        // Generate full/empty signal for memory
252
    // if read and next read pointer same as write, set empty, write will clear empty
253
    // if write and next write pointer same as read, set full, read will clear full
254
    // -----------------------------------------------------------------------------
255
        always_comb
256
        begin
257
            next_full = full;
258
            next_empty = empty;
259
                    if (read && !write)
260
                begin
261
                                next_full = 1'b0;
262
                                if (incremented_rd_ptr == wr_ptr)
263
                                        next_empty = 1'b1;
264
                end
265
                    if (write && !read)
266
                begin
267
                    next_empty = 1'b0;
268
                    if (incremented_wr_ptr == rd_ptr)
269
                        next_full = 1'b1;
270
                        end
271
            end // always_comb
272
 
273
    always_ff @(posedge clk or posedge reset)
274
        begin
275
            if (reset)
276
                begin
277
                    empty <= 1;
278
                    full  <= 0;
279
                end
280
            else
281
                begin
282
                    empty <= next_empty;
283
                    full  <= next_full;
284
                end
285
        end
286
 
287
        // --------------------
288
    // Control signals
289
    // --------------------
290
    always_comb
291
        begin
292
            in_ready            = !full;
293
            out_valid           = !empty;
294
            internal_out_ready  = out_ready;
295
                end // always_comb
296
endmodule
297
 

powered by: WebSVN 2.1.0

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