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_address_alignment.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
// $Id: //acds/main/ip/merlin/altera_merlin_axi_master_ni/address_alignment.sv#3 $
15
// $Revision: #3 $
16
// $Date: 2012/07/11 $
17
// $Author: tgngo $
18
 
19
//-----------------------------------------
20
// Address alignment:
21
// This component will aglin input address with input size
22
// Support address increment with butst type and burstwrap value
23
//-----------------------------------------
24
`timescale 1 ns / 1 ns
25
 
26
module  altera_merlin_address_alignment
27
#(
28
   parameter
29
            ADDR_W            = 12,
30
            BURSTWRAP_W       = 12,
31
            TYPE_W            = 2,
32
            SIZE_W            = 3,
33
            INCREMENT_ADDRESS = 1,
34
            NUMSYMBOLS        = 8,
35
            SELECT_BITS       = log2(NUMSYMBOLS),
36
            IN_DATA_W         = ADDR_W + (BURSTWRAP_W-1) + TYPE_W + SIZE_W,
37
            OUT_DATA_W        = ADDR_W + SELECT_BITS
38
)
39
(
40
    input                       clk,
41
    input                       reset,
42
 
43
    input [IN_DATA_W-1:0]       in_data, // in_data = {wrap_boundary, address, type, size}
44
    input                       in_valid,
45
    //output                      in_ready,
46
    input                       in_sop,
47
    input                       in_eop,
48
 
49
    output reg [OUT_DATA_W-1:0] out_data,
50
    input                       out_ready
51
    //output                      out_valid
52
 
53
);
54
typedef enum bit [1:0]
55
{
56
    FIXED       = 2'b00,
57
    INCR        = 2'b01,
58
    WRAP        = 2'b10,
59
    RESERVED    = 2'b11
60
} AxiBurstType;
61
    //----------------------------------------------------
62
    // AXSIZE decoding
63
    //
64
    // Turns the axsize value into the actual number of bytes
65
    // being transferred.
66
    // ---------------------------------------------------
67
 
68
function reg[9:0] bytes_in_transfer;
69
    input [SIZE_W-1:0] axsize;
70
    case (axsize)
71
        4'b0000: bytes_in_transfer = 10'b0000000001;
72
        4'b0001: bytes_in_transfer = 10'b0000000010;
73
        4'b0010: bytes_in_transfer = 10'b0000000100;
74
        4'b0011: bytes_in_transfer = 10'b0000001000;
75
        4'b0100: bytes_in_transfer = 10'b0000010000;
76
        4'b0101: bytes_in_transfer = 10'b0000100000;
77
        4'b0110: bytes_in_transfer = 10'b0001000000;
78
        4'b0111: bytes_in_transfer = 10'b0010000000;
79
        4'b1000: bytes_in_transfer = 10'b0100000000;
80
        4'b1001: bytes_in_transfer = 10'b1000000000;
81
        default: bytes_in_transfer = 10'b0000000001;
82
    endcase
83
endfunction
84
 
85
    //--------------------------------------
86
    //  Burst type decode
87
    //--------------------------------------
88
AxiBurstType write_burst_type;
89
 
90
function AxiBurstType burst_type_decode
91
(
92
    input [1:0] axburst
93
);
94
    AxiBurstType burst_type;
95
    begin
96
        case (axburst)
97
            2'b00    : burst_type = FIXED;
98
            2'b01    : burst_type = INCR;
99
            2'b10    : burst_type = WRAP;
100
            2'b11    : burst_type = RESERVED;
101
            default  : burst_type = INCR;
102
        endcase
103
        return burst_type;
104
    end
105
endfunction
106
 
107
    //----------------------------------------------------
108
    // Ubiquitous, familiar log2 function
109
    //----------------------------------------------------
110
function integer log2;
111
    input integer value;
112
 
113
    value = value - 1;
114
    for(log2 = 0; value > 0; log2 = log2 + 1)
115
        value = value >> 1;
116
 
117
endfunction
118
    //------------------------------------------------------------------------
119
    // This component will read address and size and check
120
    // if this is aligned or not. If not then it will align this address to the size
121
    // of the transfer:
122
    // Check alignment:
123
    //     - With data width, can define maximun how many lower bits of address to indicate this
124
    //       address align to the size
125
    //     - Ex: 32 bits data => size can be: 1, 2, 4 bytes
126
    //           For 4 bytes: when 2 lower bits of address equal 0, this is aligned address
127
    //                        addr=00|00| (0), 01|00| (4) => align to size of 4 bytes
128
    //                        addr=00|01| (1)             => start addr at 1, is not aligned to size 4 byte
129
    //           For 2 bytes: use last one bit to indicate algined or not
130
    //                        addr=000|0| (0), 001|0| (2) => align to size of 2 bytes
131
    //                        addr=000|1| (1), 001|1| (3) => not align to 2 bytes
132
    // As size runtime change, creat mask and change accordingly to size, can detect address alignment
133
    // and to align to size, apply this mask with zero to the address.
134
    //-------------------------------------------------------------------------
135
 
136
    // THe function return a vector which has width [(SELECT_BITS * 2) -1 : 0]
137
    // in which the first part contains the mask to check if this address aligned or not
138
    //              second part contains the mast to mask address to align to size
139
 
140
    function reg[(SELECT_BITS*2)-1 : 0] mask_select_and_align_address;
141
        input [ADDR_W-1:0] address;
142
        input [SIZE_W-1:0] size; // size is in AXI coding: 001 -> 2 bytes
143
 
144
        integer            i;
145
        reg [SELECT_BITS-1:0]  mask_address;
146
        reg [SELECT_BITS-1:0]  check_unaligned; // any bits =1 -> unalgined (except size = 0; 1 byte)
147
        mask_address   = '1;
148
        check_unaligned  = '0;
149
        for(i = 0; i < SELECT_BITS ; i = i + 1) begin
150
            if (i < size) begin
151
                check_unaligned[i]  = address[i];
152
                mask_address[i]       = 1'b0;
153
            end
154
        end
155
        mask_select_and_align_address   = {check_unaligned,mask_address};
156
    endfunction
157
 
158
 
159
 
160
    reg [ADDR_W-1 : 0]     in_address;
161
    reg [ADDR_W-1 : 0]     first_address_aligned;
162
    reg [SIZE_W-1 : 0]     in_size;
163
    reg [(SELECT_BITS*2)-1 : 0] output_masks;
164
    // Extract information from  input data
165
    assign in_address             = in_data[SIZE_W+ADDR_W-1 : SIZE_W];
166
    assign in_size                = in_data[SIZE_W-1 : 0];
167
 
168
    // Generate the masks
169
    always_comb
170
        begin
171
            output_masks  = mask_select_and_align_address(in_address, in_size);
172
        end
173
 
174
    // Align address if needed
175
 
176
    generate
177
        // SELECT_BITS == 1: input packet has 1 NUMSYMBOLS (1 bytes), it is aligned
178
        if (SELECT_BITS == 0)
179
            assign first_address_aligned = in_address;
180
        else begin
181
            // SELECT_BITS ==1 :input packet 2 bytes (2 SYMBOLS)
182
            wire [SELECT_BITS-1 : 0]    aligned_address_bits;
183
            if (SELECT_BITS == 1)
184
                assign aligned_address_bits   = in_address[0] & output_masks[0];
185
            else
186
                assign aligned_address_bits   = in_address[SELECT_BITS-1:0] & output_masks[SELECT_BITS-1:0];
187
            assign first_address_aligned  = {in_address[ADDR_W-1 : SELECT_BITS], aligned_address_bits};
188
        end
189
    endgenerate
190
 
191
 
192
 
193
    // Increment address base on size, first address keep the same
194
    generate
195
        if (INCREMENT_ADDRESS)
196
            begin
197
                reg [ADDR_W-1 : 0] increment_address;
198
                reg [ADDR_W-1 : 0] out_aligned_address_burst;
199
                reg [ADDR_W-1 : 0] address_burst;
200
                reg [ADDR_W-1 : 0] base_address;
201
                reg [9 : 0]        number_bytes_transfer;
202
                reg [ADDR_W-1 : 0] burstwrap_mask;
203
                reg [ADDR_W-1 : 0] burst_address_high;
204
                reg [ADDR_W-1 : 0] burst_address_low;
205
                reg [BURSTWRAP_W-2 :0] in_burstwrap_boundary;
206
                reg [TYPE_W-1 : 0]     in_type;
207
                //------------------------------------------------
208
                // Use the extended burstwrap value to split the high (constant) and
209
                // low (changing) part of the address
210
                //-----------------------------------------------
211
                assign in_type                = in_data[SIZE_W+ADDR_W+TYPE_W-1 : SIZE_W+ADDR_W];
212
                assign in_burstwrap_boundary  = in_data[IN_DATA_W-1 : ADDR_W+TYPE_W+SIZE_W];
213
                assign burstwrap_mask         = {{(ADDR_W - BURSTWRAP_W){1'b0}}, in_burstwrap_boundary};
214
                assign burst_address_high     = out_aligned_address_burst & ~burstwrap_mask;
215
                assign burst_address_low      = out_aligned_address_burst;
216
                assign number_bytes_transfer  = bytes_in_transfer(in_size);
217
                assign write_burst_type       = burst_type_decode(in_type);
218
 
219
                always @*
220
                    begin
221
                        if (in_sop)
222
                            begin
223
                                out_aligned_address_burst  = in_address;
224
                                base_address               = first_address_aligned;
225
                            end
226
                        else
227
                            begin
228
                                out_aligned_address_burst  = address_burst;
229
                                base_address               = out_aligned_address_burst;
230
                            end
231
                        case (write_burst_type)
232
                            INCR:
233
                                increment_address  = base_address + number_bytes_transfer;
234
                            WRAP:
235
                                increment_address  = ((burst_address_low + number_bytes_transfer) & burstwrap_mask) | burst_address_high;
236
                            FIXED:
237
                                increment_address  = out_aligned_address_burst;
238
                            default:
239
                                increment_address  = base_address + number_bytes_transfer;
240
                        endcase // case (write_burst_type)
241
                    end // always @ *
242
                always_ff @(posedge clk, negedge reset)
243
                    begin
244
                        if (!reset)
245
                            begin
246
                                address_burst <= '0;
247
                            end
248
                        else
249
                            begin
250
                                if (in_valid & out_ready)
251
                                    address_burst <= increment_address;
252
                            end
253
                    end
254
                // send data to output with 2 part: [mask_t0_algin][address_aligned_increment]
255
                assign   out_data  = {output_masks[SELECT_BITS-1 : 0], out_aligned_address_burst};
256
            end // if (INCREMENT_ADDRESS)
257
        else
258
            begin
259
                assign   out_data  = {output_masks[SELECT_BITS-1 : 0], first_address_aligned};
260
            end // else: !if(INCREMENT_ADDRESS)
261
 
262
    endgenerate
263
endmodule

powered by: WebSVN 2.1.0

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