source: ReferenceDesigns/w3_802.11/sysgen/wlan_phy_rx_pmd/util/wlan_rx_deinterleave_rom_gen.m

Last change on this file was 5329, checked in by murphpo, 8 years ago

Adding new wlan_rx_deinterleave_rom_gen script for Rx PHY

File size: 6.0 KB
Line 
1function deinterleave_mapping_ROM = wlan_rx_deinterleave_rom_gen()
2
3% Define numbers of coded bits per OFDM symbol for each modulation rate
4NCBPS_11a_BPSK  = 48;
5NCBPS_11a_QPSK  = 96;
6NCBPS_11a_16QAM = 192;
7NCBPS_11a_64QAM = 288;
8
9NCBPS_11n_BPSK  = 52;
10NCBPS_11n_QPSK  = 104;
11NCBPS_11n_16QAM = 208;
12NCBPS_11n_64QAM = 312;
13
14% Calculate interleaving vectors for each modulation scheme for each PHY mode
15interleave_11a_BPSK  = calc_interleave_vec_11a(NCBPS_11a_BPSK,  1);
16interleave_11a_QPSK  = calc_interleave_vec_11a(NCBPS_11a_QPSK,  2);
17interleave_11a_16QAM = calc_interleave_vec_11a(NCBPS_11a_16QAM, 4);
18interleave_11a_64QAM = calc_interleave_vec_11a(NCBPS_11a_64QAM, 6);
19interleave_11n_BPSK  = calc_interleave_vec_11n(NCBPS_11n_BPSK,  1);
20interleave_11n_QPSK  = calc_interleave_vec_11n(NCBPS_11n_QPSK,  2);
21interleave_11n_16QAM = calc_interleave_vec_11n(NCBPS_11n_16QAM, 4);
22interleave_11n_64QAM = calc_interleave_vec_11n(NCBPS_11n_64QAM, 6);
23
24% The interleave_11x vectors define the 1:1 mapping of input bit index to
25%  output bit index. The spec places the first bit (output index 0) in the
26%  lowest (most negative) frequency subcarrier, subcarrier index -26 for 11a,
27%  -28 for 11n. The Rx PHY FFT core outputs subcarriers in in natual order,
28%  starting at subcarrier 0 (DC), then +1, +2, etc. Thus the deinterleaving
29%  vectors must be rotated to align the bit indices with the IFFT
30%  subcarrier indices. This is effectivly an fftshift() operation.
31interleave_11a_BPSK  = mod(interleave_11a_BPSK  + (NCBPS_11a_BPSK/2),  NCBPS_11a_BPSK);
32interleave_11a_QPSK  = mod(interleave_11a_QPSK  + (NCBPS_11a_QPSK/2),  NCBPS_11a_QPSK);
33interleave_11a_16QAM = mod(interleave_11a_16QAM + (NCBPS_11a_16QAM/2), NCBPS_11a_16QAM);
34interleave_11a_64QAM = mod(interleave_11a_64QAM + (NCBPS_11a_64QAM/2), NCBPS_11a_64QAM);
35interleave_11n_BPSK  = mod(interleave_11n_BPSK  + (NCBPS_11n_BPSK/2),  NCBPS_11n_BPSK);
36interleave_11n_QPSK  = mod(interleave_11n_QPSK  + (NCBPS_11n_QPSK/2),  NCBPS_11n_QPSK);
37interleave_11n_16QAM = mod(interleave_11n_16QAM + (NCBPS_11n_16QAM/2), NCBPS_11n_16QAM);
38interleave_11n_64QAM = mod(interleave_11n_64QAM + (NCBPS_11n_64QAM/2), NCBPS_11n_64QAM);
39
40% The Rx PHY deinterleaver uses a single RAM to store all the bits for a
41% single OFDM symbol. The same RAM is used for all rates. The RAM stores
42% coded/punctured data bits for each subcarrier on 32-bit boundaries. By
43% allocating 1 32-bit word per subcarrier the design can use an efficient BRAM
44% architecture with 1 word write per subcarrier (concatenated LLR values) and parallel
45% 2-soft-bit reads (soft values for 2 coded bits). Even with the aspect ratio change
46% write and read operations require a single clock cycle.
47%
48% The vectors above define the interleaver mapping as bit indexes in:out.
49% The operations below convert these to mapping
50%  (bit index in) : (interleaver RAM address out) by increasing the
51% output index values to place each subcarrier's bits on a 32-bit boundary.
52% The BRAM output width is 4 bits, so the read addresses below access 8 entries
53%  per 32-bit word.
54%
55% floor(x / bits_per_sym) calculates the subcarrier index of each output bit index
56% mod(x, bits_per_sym) calculates the bit index within the subcarrier
57ramaddr_11a_BPSK  = mod(interleave_11a_BPSK, 1)  + (8 * floor(interleave_11a_BPSK  / 1));
58ramaddr_11a_QPSK  = mod(interleave_11a_QPSK, 2)  + (8 * floor(interleave_11a_QPSK  / 2));
59ramaddr_11a_16QAM = mod(interleave_11a_16QAM, 4) + (8 * floor(interleave_11a_16QAM / 4));
60ramaddr_11a_64QAM = mod(interleave_11a_64QAM, 6) + (8 * floor(interleave_11a_64QAM / 6));
61
62ramaddr_11n_BPSK  = mod(interleave_11n_BPSK, 1)  + (8 * floor(interleave_11n_BPSK  / 1));
63ramaddr_11n_QPSK  = mod(interleave_11n_QPSK, 2)  + (8 * floor(interleave_11n_QPSK  / 2));
64ramaddr_11n_16QAM = mod(interleave_11n_16QAM, 4) + (8 * floor(interleave_11n_16QAM / 4));
65ramaddr_11n_64QAM = mod(interleave_11n_64QAM, 6) + (8 * floor(interleave_11n_64QAM / 6));
66
67%Concatenate all the mapping vectors into a single vector, to be used as
68% the init value for the ROM which implements the mapping LUT. Each LUT entry
69% is used as a memory address. The Tx PHY logic constructs the RAM write address as:
70%  addr[8:0] = {phy_mode_11n[0] mod_sel[1:0] bit_ind[5:0]}
71% Each mod scheme occupies 512 entries (64 subcarriers * 8 RAM bits per subcarrier)
72deinterleave_mapping_ROM = [];
73deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11a_BPSK    zeros(1, 512-length(ramaddr_11a_BPSK))];
74deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11a_QPSK    zeros(1, 512-length(ramaddr_11a_QPSK))];
75deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11a_16QAM   zeros(1, 512-length(ramaddr_11a_16QAM))];
76deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11a_64QAM   zeros(1, 512-length(ramaddr_11a_64QAM))];
77deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11n_BPSK    zeros(1, 512-length(ramaddr_11n_BPSK))];
78deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11n_QPSK    zeros(1, 512-length(ramaddr_11n_QPSK))];
79deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11n_16QAM   zeros(1, 512-length(ramaddr_11n_16QAM))];
80deinterleave_mapping_ROM = [deinterleave_mapping_ROM   ramaddr_11n_64QAM   zeros(1, 512-length(ramaddr_11n_64QAM))];
81
82%Helper functions to calculate the interleaving vectors
83% These are implementations of the interleaving functions in the 802.11 spec
84function intlv_vec = calc_interleave_vec_11a(cbps, bpsc)
85    N_CBPS = cbps;
86    N_BPSC = bpsc;
87    s = max(N_BPSC/2, 1);
88
89    k = 0:N_CBPS-1;
90    i = (N_CBPS/16) .* mod(k,16) + floor(k/16);
91    j = s * floor(i/s) + mod( (i + N_CBPS - floor(16*i/N_CBPS)), s);
92    intlv_vec = j;
93end
94
95function intlv_vec = calc_interleave_vec_11n(cbps, bpsc)
96    N_CBPS = cbps;
97    N_BPSC = bpsc;
98    s = max(N_BPSC/2, 1);
99
100    k = 0:N_CBPS-1;
101    i = (4 * N_BPSC) .* mod(k,13) + floor(k/13);
102    j = s * floor(i/s) + mod( (i + N_CBPS - floor(13*i/N_CBPS)), s);
103    intlv_vec = j;
104end
105
106end
Note: See TracBrowser for help on using the repository browser.