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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [altera_de0_nano_soc/] [doc/] [Terasic/] [DE0_NANO_SOC/] [Demonstrations/] [FPGA/] [DE0_NANO_SOC_ADC/] [DE0_NANO_SOC_QSYS/] [synthesis/] [submodules/] [altera_merlin_reorder_memory.sv] - Blame information for rev 221

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 221 olivier.gi
// (C) 2001-2014 Altera Corporation. All rights reserved.
2
// Your use of Altera Corporation's design tools, logic functions and other
3
// software and tools, and its AMPP partner logic functions, and any output
4
// files any of the foregoing (including device programming or simulation
5
// files), and any associated documentation or information are expressly subject
6
// to the terms and conditions of the Altera Program License Subscription
7
// Agreement, Altera MegaCore Function License Agreement, or other applicable
8
// license agreement, including, without limitation, that your use is for the
9
// sole purpose of programming logic devices manufactured by Altera and sold by
10
// Altera or its authorized distributors.  Please refer to the applicable
11
// agreement for further details.
12
 
13
 
14
// $Id: //acds/rel/14.0/ip/merlin/altera_merlin_traffic_limiter/altera_merlin_reorder_memory.sv#1 $
15
// $Revision: #1 $
16
// $Date: 2014/02/16 $
17
// $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_OUTSTANIING_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 begin : pointer_signals
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
    end
156
    endgenerate
157
 
158
    // ---------------------------------
159
    // Seperate write and read pointer
160
    // for each segment in memory
161
    // ---------------------------------
162
    genvar i;
163
    generate begin : pointer_controllers
164
        for (i = 0; i < NUM_SEGMENT; i = i + 1)
165
            begin : each_segment_pointer_controller
166
                    memory_pointer_controller
167
                 #(
168
                   .ADDR_W   (ADDR_L_W)
169
                   ) reorder_memory_pointer_controller
170
                 (
171
                  .clk              (clk),
172
                  .reset            (reset),
173
                  .in_ready         (pointer_ctrl_in_ready[i]),
174
                  .in_valid         (pointer_ctrl_in_valid[i]),
175
                  .out_ready        (pointer_ctrl_out_ready[i]),
176
                  .out_valid            (pointer_ctrl_out_valid[i]),
177
                          .wr_pointer           (pointer_ctrl_wr_ptr[i]),
178
                  .rd_pointer       (pointer_ctrl_rd_ptr[i]),
179
                  .next_rd_pointer  (pointer_ctrl_next_rd_ptr[i])
180
                  );
181
            end // block: each_segment_pointer_controller
182
    end // block: pointer_controllers
183
    endgenerate
184
endmodule
185
 
186
 
187
module memory_pointer_controller
188
#(
189
    parameter ADDR_W   = 4
190
)
191
(
192
    // -------------------
193
    // Clock
194
    // -------------------
195
    input                   clk,
196
    input                   reset,
197
    // -------------------
198
    // Signals
199
    // -------------------
200
    output reg              in_ready,
201
        input                   in_valid,
202
    input                   out_ready,
203
    output reg              out_valid,
204
        // -------------------------------
205
    // Output write and read pointer
206
    // -------------------------------
207
        output [ADDR_W - 1 : 0] wr_pointer,
208
        output [ADDR_W - 1 : 0] rd_pointer,
209
    output [ADDR_W - 1 : 0] next_rd_pointer
210
);
211
 
212
        reg [ADDR_W - 1 : 0]            incremented_wr_ptr;
213
        reg [ADDR_W - 1 : 0]            incremented_rd_ptr;
214
        reg [ADDR_W - 1 : 0]            wr_ptr;
215
        reg [ADDR_W - 1 : 0]            rd_ptr;
216
        reg [ADDR_W - 1 : 0]            next_wr_ptr;
217
        reg [ADDR_W - 1 : 0]            next_rd_ptr;
218
        reg full, empty, next_full, next_empty;
219
        reg read, write, internal_out_ready, internal_out_valid;
220
 
221
        assign incremented_wr_ptr = wr_ptr + 1'b1;
222
        assign incremented_rd_ptr = rd_ptr + 1'b1;
223
        assign next_wr_ptr =  write ?  incremented_wr_ptr : wr_ptr;
224
        assign next_rd_ptr = read ? incremented_rd_ptr : rd_ptr;
225
        assign wr_pointer  = wr_ptr;
226
    assign rd_pointer  = rd_ptr;
227
    assign next_rd_pointer  = next_rd_ptr;
228
 
229
        // -------------------------------
230
    // Define write and read signals
231
    // --------------------------------
232
    // internal read, if it has any valid data
233
    // and output are ready to accepts data then a read will be performed.
234
    // -------------------------------
235
        //assign read  = internal_out_ready && internal_out_valid;
236
    assign read  = internal_out_ready && !empty;
237
        assign write = in_ready && in_valid;
238
 
239
        always_ff @(posedge clk or posedge reset)
240
        begin
241
                    if (reset)
242
                begin
243
                                wr_ptr <= 0;
244
                                rd_ptr <= 0;
245
                        end
246
            else
247
                begin
248
                                wr_ptr <= next_wr_ptr;
249
                                rd_ptr <= next_rd_ptr;
250
                        end
251
            end
252
    // ---------------------------------------------------------------------------
253
        // Generate full/empty signal for memory
254
    // if read and next read pointer same as write, set empty, write will clear empty
255
    // if write and next write pointer same as read, set full, read will clear full
256
    // -----------------------------------------------------------------------------
257
        always_comb
258
        begin
259
            next_full = full;
260
            next_empty = empty;
261
                    if (read && !write)
262
                begin
263
                                next_full = 1'b0;
264
                                if (incremented_rd_ptr == wr_ptr)
265
                                        next_empty = 1'b1;
266
                end
267
                    if (write && !read)
268
                begin
269
                    next_empty = 1'b0;
270
                    if (incremented_wr_ptr == rd_ptr)
271
                        next_full = 1'b1;
272
                        end
273
            end // always_comb
274
 
275
    always_ff @(posedge clk or posedge reset)
276
        begin
277
            if (reset)
278
                begin
279
                    empty <= 1;
280
                    full  <= 0;
281
                end
282
            else
283
                begin
284
                    empty <= next_empty;
285
                    full  <= next_full;
286
                end
287
        end
288
 
289
        // --------------------
290
    // Control signals
291
    // --------------------
292
    always_comb
293
        begin
294
            in_ready            = !full;
295
            out_valid           = !empty;
296
            internal_out_ready  = out_ready;
297
                end // always_comb
298
endmodule
299
 

powered by: WebSVN 2.1.0

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