• ZYNQ上的简单 FSK 基带发射器


    e98c9b0b6c14bbaffd3d561402760dcb.png

    绪论

    由于某种需求需要生成正弦波,因此使用 C 应用程序中的sin()函数来计算单位圆的幅度值,然后将该幅度值转换为 AD9717 的适当 DAC 代码(当然将每个角度值转换为弧度)。

    69aab3dc24e3805f83ee23c1b154e767.png

    能够使用DAC生成简单的正弦波,下一个想法就是在 SDR(软件定义无线电)中使用频率调制。

    大多数 SDR 设计都有 3 个不同的内部运行频率:一个低基带频率,用于处理来自 ADC/DAC 的数据;一个或多个中间频率,最终基带数据流作为中间步骤提升到该频率;以及最终的 RF 将输入/输出天线的输出频率。显然,最简单的起点是基带,因为它是最低频率,并且是实际模拟数据流从各个数字数据位组合在一起/提取的地方。为了进一步缩小范围,1 和 0 的数字位与某些相关模拟波形相关的确切点被称为符号映射器,它是前面提到的 SDR 基本构建块。

    因此,本项目将是一个非常简化的基带符号映射器,用于 FSK 数字调制方案的链(数字到模拟)的发送端。

    数字调制

    频移键控 (FSK) 是一种数字调制,通过更改频率来表示数据流中的不同位/符号。在其最基本的形式中,一个频率用于表示二进制 1,另一个频率用于表示二进制 0。这种形式的 FSK 被称为二进制 FSK 或 2-FSK。

    ae0d6b10412307dab564095b94bd8138.png

    从上面可以看出,1比特由大约是表示0比特的频率的两倍的频率来表示。对于 ZYNQ+SDR 来说,这意味着它需要能够分别以连续相位输出两个不同的频率。换句话说:定时在这里很重要,可以确保一个频率的相位恰好在最后一个频率的相位停止的地方出现。每个频率的一个完整周期也是每一位完成的。

    Vivado 中的逻辑设计

    由于本演示中只关注发送器端,为了处理符号映射器逻辑可能在 MM2S 读取中对来自 DDR 内存的数据流施加的背压,将带有 FSK 符号映射器的 sin LUT 放置在 AXIS 数据 FIFO 和 DAC 控制器 IP 之间。这样,FIFO 可以完成从内存的 MM2S 传输,当符号映射器逻辑每比特输出一个周期的相应频率值时,AXI DMA 不会被锁定tdata。

    d7cf6459b8847f5bb7e23230e5c96a88.png

    代码如下:

    1. `timescale 1ns / 1ps
    2. module sin_lut(
    3.     input clk,
    4.     input rst,
    5.     input [8:0] sel,
    6.     output [15:0] DAC_code
    7.     );
    8.     
    9.     reg [15:0] DAC_code;
    10.     
    11.     always @ (posedge clk)
    12.         begin
    13.             if (rst == 1'b0)
    14.                 begin 
    15.                 end
    16.             else 
    17.                 begin
    18.                     case (sel)
    19.                         9'd0   : DAC_code = 16'h0000;
    20.                         9'd1   : DAC_code = 16'h01C8;
    21.                         9'd2   : DAC_code = 16'h0390;
    22.                         9'd3   : DAC_code = 16'h0558;
    23.                         9'd4   : DAC_code = 16'h0724;
    24.                         9'd5   : DAC_code = 16'h08EC;
    25.                         9'd6   : DAC_code = 16'h0AB0;
    26.                         9'd7   : DAC_code = 16'h0C78;
    27.                         9'd8   : DAC_code = 16'h0E3C;
    28.                         9'd9   : DAC_code = 16'h1004;
    29.                         9'd10  : DAC_code = 16'h11C4;
    30.                         9'd11  : DAC_code = 16'h1388;
    31.                         9'd12  : DAC_code = 16'h1548;
    32.                         9'd13  : DAC_code = 16'h1708;
    33.                         9'd14  : DAC_code = 16'h18C4;
    34.                         9'd15  : DAC_code = 16'h1A7C;
    35.                         9'd16  : DAC_code = 16'h1C38;
    36.                         9'd17  : DAC_code = 16'h1DEC;
    37.                         9'd18  : DAC_code = 16'h1FA0;
    38.                         9'd19  : DAC_code = 16'h2154;
    39.                         9'd20  : DAC_code = 16'h2304;
    40.                         9'd21  : DAC_code = 16'h24B0;
    41.                         9'd22  : DAC_code = 16'h2658;
    42.                         9'd23  : DAC_code = 16'h2800;
    43.                         9'd24  : DAC_code = 16'h29A4;
    44.                         9'd25  : DAC_code = 16'h2B44;
    45.                         9'd26  : DAC_code = 16'h2CE0;
    46.                         9'd27  : DAC_code = 16'h2E78;
    47.                         9'd28  : DAC_code = 16'h3010;
    48.                         9'd29  : DAC_code = 16'h31A0;
    49.                         9'd30  : DAC_code = 16'h3330;
    50.                         9'd31  : DAC_code = 16'h34B8;
    51.                         9'd32  : DAC_code = 16'h3640;
    52.                         9'd33  : DAC_code = 16'h37C0;
    53.                         9'd34  : DAC_code = 16'h3940;
    54.                         9'd35  : DAC_code = 16'h3AB8;
    55.                         9'd36  : DAC_code = 16'h3C2C;
    56.                         9'd37  : DAC_code = 16'h3D9C;
    57.                         9'd38  : DAC_code = 16'h3F08;
    58.                         9'd39  : DAC_code = 16'h406C;
    59.                         9'd40  : DAC_code = 16'h41D0;
    60.                         9'd41  : DAC_code = 16'h432C;
    61.                         9'd42  : DAC_code = 16'h4480;
    62.                         9'd43  : DAC_code = 16'h45D0;
    63.                         9'd44  : DAC_code = 16'h471C;
    64.                         9'd45  : DAC_code = 16'h4864;
    65.                         9'd46  : DAC_code = 16'h49A4;
    66.                         9'd47  : DAC_code = 16'h4AE0;
    67.                         9'd48  : DAC_code = 16'h4C14;
    68.                         9'd49  : DAC_code = 16'h4D44;
    69.                         9'd50  : DAC_code = 16'h4E6C;
    70.                         9'd51  : DAC_code = 16'h4F90;
    71.                         9'd52  : DAC_code = 16'h50AC;
    72.                         9'd53  : DAC_code = 16'h51C4;
    73.                         9'd54  : DAC_code = 16'h52D4;
    74.                         9'd55  : DAC_code = 16'h53DC;
    75.                         9'd56  : DAC_code = 16'h54E0;
    76.                         9'd57  : DAC_code = 16'h55DC;
    77.                         9'd58  : DAC_code = 16'h56D4;
    78.                         9'd59  : DAC_code = 16'h57C0;
    79.                         9'd60  : DAC_code = 16'h58A8;
    80.                         9'd61  : DAC_code = 16'h598C;
    81.                         9'd62  : DAC_code = 16'h5A64;
    82.                         9'd63  : DAC_code = 16'h5B38;
    83.                         9'd64  : DAC_code = 16'h5C04;
    84.                         9'd65  : DAC_code = 16'h5CC8;
    85.                         9'd66  : DAC_code = 16'h5D88;
    86.                         9'd67  : DAC_code = 16'h5E3C;
    87.                         9'd68  : DAC_code = 16'h5EEC;
    88.                         9'd69  : DAC_code = 16'h5F94;
    89.                         9'd70  : DAC_code = 16'h6034;
    90.                         9'd71  : DAC_code = 16'h60CC;
    91.                         9'd72  : DAC_code = 16'h6160;
    92.                         9'd73  : DAC_code = 16'h61E8;
    93.                         9'd74  : DAC_code = 16'h6268;
    94.                         9'd75  : DAC_code = 16'h62E4;
    95.                         9'd76  : DAC_code = 16'h6358;
    96.                         9'd77  : DAC_code = 16'h63C0;
    97.                         9'd78  : DAC_code = 16'h6424;
    98.                         9'd79  : DAC_code = 16'h6480;
    99.                         9'd80  : DAC_code = 16'h64D4;
    100.                         9'd81  : DAC_code = 16'h6520;
    101.                         9'd82  : DAC_code = 16'h6564;
    102.                         9'd83  : DAC_code = 16'h659C;
    103.                         9'd84  : DAC_code = 16'h65D0;
    104.                         9'd85  : DAC_code = 16'h65FC;
    105.                         9'd86  : DAC_code = 16'h6620;
    106.                         9'd87  : DAC_code = 16'h663C;
    107.                         9'd88  : DAC_code = 16'h6650;
    108.                         9'd89  : DAC_code = 16'h665C;
    109.                         9'd90  : DAC_code = 16'h6660;
    110.                         9'd91  : DAC_code = 16'h665C;
    111.                         9'd92  : DAC_code = 16'h6650;
    112.                         9'd93  : DAC_code = 16'h663C;
    113.                         9'd94  : DAC_code = 16'h6620;
    114.                         9'd95  : DAC_code = 16'h65FC;
    115.                         9'd96  : DAC_code = 16'h65D0;
    116.                         9'd97  : DAC_code = 16'h659C;
    117.                         9'd98  : DAC_code = 16'h6564;
    118.                         9'd99  : DAC_code = 16'h6520;
    119.                         9'd100 : DAC_code = 16'h64D4;
    120.                         9'd101 : DAC_code = 16'h6480;
    121.                         9'd102 : DAC_code = 16'h6424;
    122.                         9'd103 : DAC_code = 16'h63C0;
    123.                         9'd104 : DAC_code = 16'h6358;
    124.                         9'd105 : DAC_code = 16'h62E4;
    125.                         9'd106 : DAC_code = 16'h6268;
    126.                         9'd107 : DAC_code = 16'h61E8;
    127.                         9'd108 : DAC_code = 16'h6160;
    128.                         9'd109 : DAC_code = 16'h60CC;
    129.                         9'd110 : DAC_code = 16'h6034;
    130.                         9'd111 : DAC_code = 16'h5F94;
    131.                         9'd112 : DAC_code = 16'h5EEC;
    132.                         9'd113 : DAC_code = 16'h5E3C;
    133.                         9'd114 : DAC_code = 16'h5D88;
    134.                         9'd115 : DAC_code = 16'h5CC8;
    135.                         9'd116 : DAC_code = 16'h5C04;
    136.                         9'd117 : DAC_code = 16'h5B38;
    137.                         9'd118 : DAC_code = 16'h5A64;
    138.                         9'd119 : DAC_code = 16'h598C;
    139.                         9'd120 : DAC_code = 16'h58A8;
    140.                         9'd121 : DAC_code = 16'h57C0;
    141.                         9'd122 : DAC_code = 16'h56D4;
    142.                         9'd123 : DAC_code = 16'h55DC;
    143.                         9'd124 : DAC_code = 16'h54E0;
    144.                         9'd125 : DAC_code = 16'h53DC;
    145.                         9'd126 : DAC_code = 16'h52D4;
    146.                         9'd127 : DAC_code = 16'h51C4;
    147.                         9'd128 : DAC_code = 16'h50AC;
    148.                         9'd129 : DAC_code = 16'h4F90;
    149.                         9'd130 : DAC_code = 16'h4E6C;
    150.                         9'd131 : DAC_code = 16'h4D44;
    151.                         9'd132 : DAC_code = 16'h4C14;
    152.                         9'd133 : DAC_code = 16'h4AE0;
    153.                         9'd134 : DAC_code = 16'h49A4;
    154.                         9'd135 : DAC_code = 16'h4864;
    155.                         9'd136 : DAC_code = 16'h471C;
    156.                         9'd137 : DAC_code = 16'h45D0;
    157.                         9'd138 : DAC_code = 16'h4480;
    158.                         9'd139 : DAC_code = 16'h432C;
    159.                         9'd140 : DAC_code = 16'h41D0;
    160.                         9'd141 : DAC_code = 16'h406C;
    161.                         9'd142 : DAC_code = 16'h3F08;
    162.                         9'd143 : DAC_code = 16'h3D9C;
    163.                         9'd144 : DAC_code = 16'h3C2C;
    164.                         9'd145 : DAC_code = 16'h3AB8;
    165.                         9'd146 : DAC_code = 16'h3940;
    166.                         9'd147 : DAC_code = 16'h37C0;
    167.                         9'd148 : DAC_code = 16'h3640;
    168.                         9'd149 : DAC_code = 16'h34B8;
    169.                         9'd150 : DAC_code = 16'h3330;
    170.                         9'd151 : DAC_code = 16'h31A0;
    171.                         9'd152 : DAC_code = 16'h3010;
    172.                         9'd153 : DAC_code = 16'h2E78;
    173.                         9'd154 : DAC_code = 16'h2CE0;
    174.                         9'd155 : DAC_code = 16'h2B44;
    175.                         9'd156 : DAC_code = 16'h29A4;
    176.                         9'd157 : DAC_code = 16'h2800;
    177.                         9'd158 : DAC_code = 16'h2658;
    178.                         9'd159 : DAC_code = 16'h24B0;
    179.                         9'd160 : DAC_code = 16'h2304;
    180.                         9'd161 : DAC_code = 16'h2154;
    181.                         9'd162 : DAC_code = 16'h1FA0;
    182.                         9'd163 : DAC_code = 16'h1DEC;
    183.                         9'd164 : DAC_code = 16'h1C38;
    184.                         9'd165 : DAC_code = 16'h1A7C;
    185.                         9'd166 : DAC_code = 16'h18C4;
    186.                         9'd167 : DAC_code = 16'h1708;
    187.                         9'd168 : DAC_code = 16'h1548;
    188.                         9'd169 : DAC_code = 16'h1388;
    189.                         9'd170 : DAC_code = 16'h11C4;
    190.                         9'd171 : DAC_code = 16'h1004;
    191.                         9'd172 : DAC_code = 16'h0E3C;
    192.                         9'd173 : DAC_code = 16'h0C78;
    193.                         9'd174 : DAC_code = 16'h0AB0;
    194.                         9'd175 : DAC_code = 16'h08EC;
    195.                         9'd176 : DAC_code = 16'h0724;
    196.                         9'd177 : DAC_code = 16'h0558;
    197.                         9'd178 : DAC_code = 16'h0390;
    198.                         9'd179 : DAC_code = 16'h01C8;
    199.                         9'd180 : DAC_code = 16'h0000;
    200.                         9'd181 : DAC_code = 16'hFE37;
    201.                         9'd182 : DAC_code = 16'hFC6F;
    202.                         9'd183 : DAC_code = 16'hFAA7;
    203.                         9'd184 : DAC_code = 16'hF8DB;
    204.                         9'd185 : DAC_code = 16'hF713;
    205.                         9'd186 : DAC_code = 16'hF54F;
    206.                         9'd187 : DAC_code = 16'hF387;
    207.                         9'd188 : DAC_code = 16'hF1C3;
    208.                         9'd189 : DAC_code = 16'hEFFB;
    209.                         9'd190 : DAC_code = 16'hEE3B;
    210.                         9'd191 : DAC_code = 16'hEC77;
    211.                         9'd192 : DAC_code = 16'hEAB7;
    212.                         9'd193 : DAC_code = 16'hE8F7;
    213.                         9'd194 : DAC_code = 16'hE73B;
    214.                         9'd195 : DAC_code = 16'hE583;
    215.                         9'd196 : DAC_code = 16'hE3C7;
    216.                         9'd197 : DAC_code = 16'hE213;
    217.                         9'd198 : DAC_code = 16'hE05F;
    218.                         9'd199 : DAC_code = 16'hDEAB;
    219.                         9'd200 : DAC_code = 16'hDCFB;
    220.                         9'd201 : DAC_code = 16'hDB4F;
    221.                         9'd202 : DAC_code = 16'hD9A7;
    222.                         9'd203 : DAC_code = 16'hD7FF;
    223.                         9'd204 : DAC_code = 16'hD65B;
    224.                         9'd205 : DAC_code = 16'hD4BB;
    225.                         9'd206 : DAC_code = 16'hD31F;
    226.                         9'd207 : DAC_code = 16'hD187;
    227.                         9'd208 : DAC_code = 16'hCFEF;
    228.                         9'd209 : DAC_code = 16'hCE5F;
    229.                         9'd210 : DAC_code = 16'hCCCF;
    230.                         9'd211 : DAC_code = 16'hCB47;
    231.                         9'd212 : DAC_code = 16'hC9BF;
    232.                         9'd213 : DAC_code = 16'hC83F;
    233.                         9'd214 : DAC_code = 16'hC6BF;
    234.                         9'd215 : DAC_code = 16'hC547;
    235.                         9'd216 : DAC_code = 16'hC3D3;
    236.                         9'd217 : DAC_code = 16'hC263;
    237.                         9'd218 : DAC_code = 16'hC0F7;
    238.                         9'd219 : DAC_code = 16'hBF93;
    239.                         9'd220 : DAC_code = 16'hBE2F;
    240.                         9'd221 : DAC_code = 16'hBCD3;
    241.                         9'd222 : DAC_code = 16'hBB7F;
    242.                         9'd223 : DAC_code = 16'hBA2F;
    243.                         9'd224 : DAC_code = 16'hB8E3;
    244.                         9'd225 : DAC_code = 16'hB79B;
    245.                         9'd226 : DAC_code = 16'hB65B;
    246.                         9'd227 : DAC_code = 16'hB51F;
    247.                         9'd228 : DAC_code = 16'hB3EB;
    248.                         9'd229 : DAC_code = 16'hB2BB;
    249.                         9'd230 : DAC_code = 16'hB193;
    250.                         9'd231 : DAC_code = 16'hB06F;
    251.                         9'd232 : DAC_code = 16'hAF53;
    252.                         9'd233 : DAC_code = 16'hAE3B;
    253.                         9'd234 : DAC_code = 16'hAD2B;
    254.                         9'd235 : DAC_code = 16'hAC23;
    255.                         9'd236 : DAC_code = 16'hAB1F;
    256.                         9'd237 : DAC_code = 16'hAA23;
    257.                         9'd238 : DAC_code = 16'hA92B;
    258.                         9'd239 : DAC_code = 16'hA83F;
    259.                         9'd240 : DAC_code = 16'hA757;
    260.                         9'd241 : DAC_code = 16'hA673;
    261.                         9'd242 : DAC_code = 16'hA59B;
    262.                         9'd243 : DAC_code = 16'hA4C7;
    263.                         9'd244 : DAC_code = 16'hA3FB;
    264.                         9'd245 : DAC_code = 16'hA337;
    265.                         9'd246 : DAC_code = 16'hA277;
    266.                         9'd247 : DAC_code = 16'hA1C3;
    267.                         9'd248 : DAC_code = 16'hA113;
    268.                         9'd249 : DAC_code = 16'hA06B;
    269.                         9'd250 : DAC_code = 16'h9FCB;
    270.                         9'd251 : DAC_code = 16'h9F33;
    271.                         9'd252 : DAC_code = 16'h9E9F;
    272.                         9'd253 : DAC_code = 16'h9E17;
    273.                         9'd254 : DAC_code = 16'h9D97;
    274.                         9'd255 : DAC_code = 16'h9D1B;
    275.                         9'd256 : DAC_code = 16'h9CA7;
    276.                         9'd257 : DAC_code = 16'h9C3F;
    277.                         9'd258 : DAC_code = 16'h9BDB;
    278.                         9'd259 : DAC_code = 16'h9B7F;
    279.                         9'd260 : DAC_code = 16'h9B2B;
    280.                         9'd261 : DAC_code = 16'h9ADF;
    281.                         9'd262 : DAC_code = 16'h9A9B;
    282.                         9'd263 : DAC_code = 16'h9A63;
    283.                         9'd264 : DAC_code = 16'h9A2F;
    284.                         9'd265 : DAC_code = 16'h9A03;
    285.                         9'd266 : DAC_code = 16'h99DF;
    286.                         9'd267 : DAC_code = 16'h99C3;
    287.                         9'd268 : DAC_code = 16'h99AF;
    288.                         9'd269 : DAC_code = 16'h99A3;
    289.                         9'd270 : DAC_code = 16'h999F;
    290.                         9'd271 : DAC_code = 16'h99A3;
    291.                         9'd272 : DAC_code = 16'h99AF;
    292.                         9'd273 : DAC_code = 16'h99C3;
    293.                         9'd274 : DAC_code = 16'h99DF;
    294.                         9'd275 : DAC_code = 16'h9A03;
    295.                         9'd276 : DAC_code = 16'h9A2F;
    296.                         9'd277 : DAC_code = 16'h9A63;
    297.                         9'd278 : DAC_code = 16'h9A9B;
    298.                         9'd279 : DAC_code = 16'h9ADF;
    299.                         9'd280 : DAC_code = 16'h9B2B;
    300.                         9'd281 : DAC_code = 16'h9B7F;
    301.                         9'd282 : DAC_code = 16'h9BDB;
    302.                         9'd283 : DAC_code = 16'h9C3F;
    303.                         9'd284 : DAC_code = 16'h9CA7;
    304.                         9'd285 : DAC_code = 16'h9D1B;
    305.                         9'd286 : DAC_code = 16'h9D97;
    306.                         9'd287 : DAC_code = 16'h9E17;
    307.                         9'd288 : DAC_code = 16'h9E9F;
    308.                         9'd289 : DAC_code = 16'h9F33;
    309.                         9'd290 : DAC_code = 16'h9FCB;
    310.                         9'd291 : DAC_code = 16'hA06B;
    311.                         9'd292 : DAC_code = 16'hA113;
    312.                         9'd293 : DAC_code = 16'hA1C3;
    313.                         9'd294 : DAC_code = 16'hA277;
    314.                         9'd295 : DAC_code = 16'hA337;
    315.                         9'd296 : DAC_code = 16'hA3FB;
    316.                         9'd297 : DAC_code = 16'hA4C7;
    317.                         9'd298 : DAC_code = 16'hA59B;
    318.                         9'd299 : DAC_code = 16'hA673;
    319.                         9'd300 : DAC_code = 16'hA757;
    320.                         9'd301 : DAC_code = 16'hA83F;
    321.                         9'd302 : DAC_code = 16'hA92B;
    322.                         9'd303 : DAC_code = 16'hAA23;
    323.                         9'd304 : DAC_code = 16'hAB1F;
    324.                         9'd305 : DAC_code = 16'hAC23;
    325.                         9'd306 : DAC_code = 16'hAD2B;
    326.                         9'd307 : DAC_code = 16'hAE3B;
    327.                         9'd308 : DAC_code = 16'hAF53;
    328.                         9'd309 : DAC_code = 16'hB06F;
    329.                         9'd310 : DAC_code = 16'hB193;
    330.                         9'd311 : DAC_code = 16'hB2BB;
    331.                         9'd312 : DAC_code = 16'hB3EB;
    332.                         9'd313 : DAC_code = 16'hB51F;
    333.                         9'd314 : DAC_code = 16'hB65B;
    334.                         9'd315 : DAC_code = 16'hB79B;
    335.                         9'd316 : DAC_code = 16'hB8E3;
    336.                         9'd317 : DAC_code = 16'hBA2F;
    337.                         9'd318 : DAC_code = 16'hBB7F;
    338.                         9'd319 : DAC_code = 16'hBCD3;
    339.                         9'd320 : DAC_code = 16'hBE2F;
    340.                         9'd321 : DAC_code = 16'hBF93;
    341.                         9'd322 : DAC_code = 16'hC0F7;
    342.                         9'd323 : DAC_code = 16'hC263;
    343.                         9'd324 : DAC_code = 16'hC3D3;
    344.                         9'd325 : DAC_code = 16'hC547;
    345.                         9'd326 : DAC_code = 16'hC6BF;
    346.                         9'd327 : DAC_code = 16'hC83F;
    347.                         9'd328 : DAC_code = 16'hC9BF;
    348.                         9'd329 : DAC_code = 16'hCB47;
    349.                         9'd330 : DAC_code = 16'hCCCF;
    350.                         9'd331 : DAC_code = 16'hCE5F;
    351.                         9'd332 : DAC_code = 16'hCFEF;
    352.                         9'd333 : DAC_code = 16'hD187;
    353.                         9'd334 : DAC_code = 16'hD31F;
    354.                         9'd335 : DAC_code = 16'hD4BB;
    355.                         9'd336 : DAC_code = 16'hD65B;
    356.                         9'd337 : DAC_code = 16'hD7FF;
    357.                         9'd338 : DAC_code = 16'hD9A7;
    358.                         9'd339 : DAC_code = 16'hDB4F;
    359.                         9'd340 : DAC_code = 16'hDCFB;
    360.                         9'd341 : DAC_code = 16'hDEAB;
    361.                         9'd342 : DAC_code = 16'hE05F;
    362.                         9'd343 : DAC_code = 16'hE213;
    363.                         9'd344 : DAC_code = 16'hE3C7;
    364.                         9'd345 : DAC_code = 16'hE583;
    365.                         9'd346 : DAC_code = 16'hE73B;
    366.                         9'd347 : DAC_code = 16'hE8F7;
    367.                         9'd348 : DAC_code = 16'hEAB7;
    368.                         9'd349 : DAC_code = 16'hEC77;
    369.                         9'd350 : DAC_code = 16'hEE3B;
    370.                         9'd351 : DAC_code = 16'hEFFB;
    371.                         9'd352 : DAC_code = 16'hF1C3;
    372.                         9'd353 : DAC_code = 16'hF387;
    373.                         9'd354 : DAC_code = 16'hF54F;
    374.                         9'd355 : DAC_code = 16'hF713;
    375.                         9'd356 : DAC_code = 16'hF8DB;
    376.                         9'd357 : DAC_code = 16'hFAA7;
    377.                         9'd358 : DAC_code = 16'hFC6F;
    378.                         9'd359 : DAC_code = 16'hFE37;
    379.                         9'd360 : DAC_code = 16'h0000;
    380.                         default : DAC_code = 16'h0000;
    381.                     endcase
    382.                 end
    383.         end
    384.     
    385. endmodule

    由于 sin LUT 的 case 语句中的选择值是正弦波单位圆的每个 360 度值,因此计数器从 0 到 360 递增的速度最终设置了输出正弦波的频率。

    sin LUT 上方的逻辑中需要三个计数器:一个计数器用于对 sin LUT 选择从 0 到 359 的度数进行计数,一个计数器用于计算频率 0 的增量之间的延迟,以及一个计数器用于计算频率 0 的增量之间的延迟。频率 1.

    1. always @ (posedge clk)
    2.     begin 
    3.         if (rst == 1'b0)
    4.             begin
    5.                 degree_cntr <= 9'd0;
    6.                 degree_cntr_done <= 1'b0; 
    7.             end
    8.         else if (incr_degree_cntr == 1'b1)
    9.             begin
    10.                 if (degree_cntr < unit_circle_deg)
    11.                     begin
    12.                         degree_cntr <= degree_cntr + 1;
    13.                         degree_cntr_done <= 1'b0;
    14.                     end
    15.                 else
    16.                     begin
    17.                         degree_cntr <= 9'd0;
    18.                         degree_cntr_done <= 1'b1;
    19.                     end
    20.             end
    21.         else
    22.             begin
    23.                 degree_cntr <= degree_cntr;
    24.             end
    25.     end 
    26. always @ (posedge clk)
    27.     begin 
    28.         if (rst == 1'b0)
    29.             begin
    30.                 incr_degree_cntr = 1'b0;
    31.                 period_cntr <= 3'd0;
    32.             end
    33.         else
    34.             begin
    35.                 if (period_cntr == period)
    36.                     begin
    37.                         incr_degree_cntr = 1'b1;
    38.                         period_cntr <= 3'd0;
    39.                     end
    40.                 else
    41.                     begin 
    42.                         incr_degree_cntr = 1'b0;
    43.                         period_cntr <= period_cntr + 1;
    44.                     end 
    45.             end
    46.     end 
    47. always @ (posedge clk)
    48.     begin 
    49.         if (rst == 1'b0)
    50.             begin
    51.                 tdata_sel_cntr <= 5'd0;
    52.             end 
    53.         else 
    54.             begin
    55.                 if (degree_cntr_done == 1'b1)
    56.                     begin
    57.                         tdata_sel_cntr <= tdata_sel_cntr + 1;
    58.                     end
    59.                 else
    60.                     begin
    61.                         tdata_sel_cntr <= tdata_sel_cntr;
    62.                     end
    63.             end 
    64.     end

    还需要一个并行到串行转换器,通过 MM2S 传输从 DDR 发出的数据包的 AXI Stream 接口获取 32 位数据,并将其串行化,可以通过 MM2S 传输输出该位各自频率的一个周期。 DAC一次。这就是 2-FSK 的局限性暴露出来的地方:一次只能传输一位。

    1. always @ (tdata_sel_cntr)
    2.     begin 
    3.         case (tdata_sel_cntr) 
    4.             32'd0   : 
    5.                 begin
    6.                     current_tx_bit <= tdata[0];
    7.                     tx_pkt_done <= 1'b0;
    8.                 end 
    9.             32'd1   : 
    10.                 begin
    11.                      current_tx_bit <= tdata[1];
    12.                      tx_pkt_done <= 1'b0;
    13.                 end 
    14.             32'd2   : 
    15.                 begin
    16.                      current_tx_bit <= tdata[2];
    17.                      tx_pkt_done <= 1'b0;
    18.                 end 
    19.             32'd3   : 
    20.                 begin
    21.                      current_tx_bit <= tdata[3];
    22.                      tx_pkt_done <= 1'b0;
    23.                 end 
    24.             32'd4   : 
    25.                 begin
    26.                      current_tx_bit <= tdata[4];
    27.                      tx_pkt_done <= 1'b0;
    28.                 end 
    29.             32'd5   : 
    30.                 begin
    31.                      current_tx_bit <= tdata[5];
    32.                      tx_pkt_done <= 1'b0;
    33.                 end 
    34.             32'd6   : 
    35.                 begin
    36.                      current_tx_bit <= tdata[6];
    37.                      tx_pkt_done <= 1'b0;
    38.                 end 
    39.             32'd7   : 
    40.                 begin
    41.                      current_tx_bit <= tdata[7];
    42.                      tx_pkt_done <= 1'b0;
    43.                 end 
    44.             32'd8   : 
    45.                 begin
    46.                      current_tx_bit <= tdata[8];
    47.                      tx_pkt_done <= 1'b0;
    48.                 end 
    49.             32'd9   : 
    50.                 begin
    51.                      current_tx_bit <= tdata[9];
    52.                      tx_pkt_done <= 1'b0;
    53.                 end 
    54.             32'd10  : 
    55.                 begin
    56.                      current_tx_bit <= tdata[10];
    57.                      tx_pkt_done <= 1'b0;
    58.                 end 
    59.             32'd11  : 
    60.                 begin
    61.                      current_tx_bit <= tdata[11];
    62.                      tx_pkt_done <= 1'b0;
    63.                 end 
    64.             32'd12  : 
    65.                 begin
    66.                      current_tx_bit <= tdata[12];
    67.                      tx_pkt_done <= 1'b0;
    68.                 end 
    69.             32'd13  : 
    70.                 begin
    71.                      current_tx_bit <= tdata[13];
    72.                      tx_pkt_done <= 1'b0;
    73.                 end 
    74.             32'd14  : 
    75.                 begin
    76.                      current_tx_bit <= tdata[14];
    77.                      tx_pkt_done <= 1'b0;
    78.                 end 
    79.             32'd15  : 
    80.                 begin
    81.                      current_tx_bit <= tdata[15];
    82.                      tx_pkt_done <= 1'b0;
    83.                 end 
    84.             32'd16  : 
    85.                 begin
    86.                      current_tx_bit <= tdata[16];
    87.                      tx_pkt_done <= 1'b0;
    88.                 end 
    89.             32'd17  : 
    90.                 begin
    91.                      current_tx_bit <= tdata[17];
    92.                      tx_pkt_done <= 1'b0;
    93.                 end 
    94.             32'd18  : 
    95.                 begin
    96.                      current_tx_bit <= tdata[18];
    97.                      tx_pkt_done <= 1'b0;
    98.                 end 
    99.             32'd19  : 
    100.                 begin
    101.                      current_tx_bit <= tdata[19];
    102.                      tx_pkt_done <= 1'b0;
    103.                 end 
    104.             32'd20  : 
    105.                 begin
    106.                      current_tx_bit <= tdata[20];
    107.                      tx_pkt_done <= 1'b0;
    108.                 end 
    109.             32'd21  : 
    110.                 begin
    111.                      current_tx_bit <= tdata[21];
    112.                      tx_pkt_done <= 1'b0;
    113.                 end 
    114.             32'd22  : 
    115.                 begin
    116.                      current_tx_bit <= tdata[22];
    117.                      tx_pkt_done <= 1'b0;
    118.                 end 
    119.             32'd23  : 
    120.                 begin
    121.                      current_tx_bit <= tdata[23];
    122.                      tx_pkt_done <= 1'b0;
    123.                 end 
    124.             32'd24  : 
    125.                 begin
    126.                      current_tx_bit <= tdata[24];
    127.                      tx_pkt_done <= 1'b0;
    128.                 end 
    129.             32'd25  : 
    130.                 begin
    131.                      current_tx_bit <= tdata[25];
    132.                      tx_pkt_done <= 1'b0;
    133.                 end 
    134.             32'd26  : 
    135.                 begin
    136.                      current_tx_bit <= tdata[26];
    137.                      tx_pkt_done <= 1'b0;
    138.                 end 
    139.             32'd27  : 
    140.                 begin
    141.                      current_tx_bit <= tdata[27];
    142.                      tx_pkt_done <= 1'b0;
    143.                 end 
    144.             32'd28  : 
    145.                 begin
    146.                      current_tx_bit <= tdata[28];
    147.                      tx_pkt_done <= 1'b0;
    148.                 end 
    149.             32'd29  : 
    150.                 begin
    151.                      current_tx_bit <= tdata[29];
    152.                      tx_pkt_done <= 1'b0;
    153.                 end 
    154.             32'd30  : 
    155.                 begin
    156.                      current_tx_bit <= tdata[30];
    157.                      tx_pkt_done <= 1'b0;
    158.                 end 
    159.             32'd31  : 
    160.                 begin
    161.                      current_tx_bit <= tdata[31];
    162.                      tx_pkt_done <= 1'b1;
    163.                 end 
    164.             default : 
    165.                 begin
    166.                     current_tx_bit <= 1'b0;
    167.                     tx_pkt_done <= 1'b0;
    168.                 end
    169.         endcase 
    170.     end
    171. always @ (posedge clk)
    172.     begin 
    173.         if (current_tx_bit == 1'b1)
    174.             period <= T1_period;
    175.         else
    176.             period <= T0_period;
    177.     end

    最后,AXI Stream 接口只需要围绕上述逻辑,使用从接口接收来自 AXIS FIFO 的数据,并使用主接口将数据输出到 DAC 控制器。

    1. `timescale 1ns / 1ps
    2. module sin_axis(
    3.     input clk,
    4.     input reset,
    5.     input [31:0] s_axis_tdata,
    6.     input [3:0] s_axis_tkeep,
    7.     input s_axis_tlast,
    8.     output reg s_axis_tready,
    9.     input s_axis_tvalid,
    10.     output reg [31:0] m_axis_tdata,
    11.     output reg [3:0] m_axis_tkeep,
    12.     output reg m_axis_tlast,
    13.     input m_axis_tready,
    14.     output reg m_axis_tvalid, 
    15.     output [2:0] state_reg
    16.     );
    17.     
    18.     sin_sm sin_sm_i(
    19.         .clk(clk),
    20.         .rst(reset),
    21.         .tdata_slave(tdata_slave),
    22.         .tdata_master(tdata_master),
    23.         .tx_pkt_done(tx_pkt_done)
    24.     );
    25.     
    26.     
    27.     reg tlast;
    28.     reg [2:0] state_reg;
    29.     
    30.     wire tx_pkt_done;
    31.     wire [31:0] tdata_master;
    32.     reg [31:0] tdata_slave;
    33.     
    34.     
    35.     parameter init               = 3'd0;
    36.     parameter SetSlaveTready     = 3'd1;
    37.     parameter CheckSlaveTvalid   = 3'd2;
    38.     parameter ProcessTdata       = 3'd3;
    39.     parameter CheckTlast         = 3'd4;
    40.     
    41.     always @ (posedge clk)
    42.         begin
    43.    // Default outputs            
    44.    m_axis_tvalid <= 1'b0;
    45.             
    46.             if (reset == 1'b0)
    47.                 begin
    48.                     tlast <= 1'b0;
    49.                     tdata_slave[31:0] <= 32'd0;
    50.                     s_axis_tready <= 1'b0;
    51.                     m_axis_tdata[31:0] <= 32'd0;
    52.                     m_axis_tkeep <= 4'h0;
    53.                     m_axis_tlast <= 1'b0;
    54.                     state_reg <= init;
    55.                 end
    56.             else
    57.                 begin
    58.                 
    59.                     case(state_reg) 
    60.                         init : // 0 
    61.                             begin
    62.                                 tlast <= 1'b0;
    63.                                 tdata_slave[31:0] <= 32'd0;
    64.                                 s_axis_tready <= 1'b0;
    65.                                 m_axis_tdata[31:0] <= 32'd0;
    66.                                 m_axis_tkeep <= 4'h0;
    67.                                 m_axis_tlast <= 1'b0;
    68.                                 state_reg <= SetSlaveTready;
    69.                             end 
    70.                             
    71.                         SetSlaveTready : // 1
    72.                             begin
    73.                                 s_axis_tready <= 1'b1;
    74.                                 state_reg <= CheckSlaveTvalid;
    75.                             end 
    76.                             
    77.                         CheckSlaveTvalid : // 2
    78.                             begin
    79.                                 if (s_axis_tkeep == 4'hf && s_axis_tvalid == 1'b1)
    80.                                     begin
    81.                                         s_axis_tready <= 1'b0;
    82.                                         tlast <= s_axis_tlast;
    83.                                         tdata_slave[31:0] <= s_axis_tdata[31:0];
    84.                                         state_reg <= ProcessTdata;
    85.                                     end
    86.                                 else
    87.                                     begin 
    88.                                         tdata_slave[31:0] <= 32'd0;
    89.                                         state_reg <= CheckSlaveTvalid;
    90.                                     end 
    91.                             end
    92.                             
    93.                         ProcessTdata : // 3
    94.                             begin 
    95.                                 m_axis_tkeep <= 4'hf;
    96.                                 m_axis_tlast <= tlast;
    97.                                 m_axis_tvalid <= 1'b1;
    98.                                 m_axis_tdata[31:0] <= tdata_master[31:0];
    99.                                 
    100.                                 if (m_axis_tready == 1'b1 && tx_pkt_done == 1'b1)
    101.                                     begin 
    102.                                         state_reg <= CheckTlast;
    103.                                     end 
    104.                                 else
    105.                                     begin 
    106.                                         state_reg <= ProcessTdata;
    107.                                     end 
    108.                             end
    109.                             
    110.                         CheckTlast : // 4
    111.                             begin 
    112.                                 if (m_axis_tlast == 1'b1)
    113.                                     begin    
    114.                                         state_reg <= init;
    115.                                     end
    116.                                 else if (m_axis_tready == 1'b1)
    117.                                     begin
    118.                                         state_reg <= SetSlaveTready;
    119.                                     end
    120.                                 else 
    121.                                     begin 
    122.                                         state_reg <= CheckTlast;
    123.                                     end 
    124.                             end 
    125.                             
    126.                     endcase 
    127.                 end
    128.         end
    129. endmodule

    完整的代码见最后。

    Vitis 软件

    由于生成正弦波的所有逻辑都是在 Verilog 的 HDL 中处理的,因此 C 代码中唯一剩下的就是控制 MM2S 传输(源文件也附在下面):

    1. int main()
    2. {
    3.     init_platform();
    4.     XAxiDma_Config *CfgPtr; //DMA configuration pointer
    5.     int Status, Index;
    6.     u8 *TxBufferPtr;
    7.     TxBufferPtr = (u8 *)TX_BUFFER_BASE;
    8.     for(Index = 0; Index < MAX_PKT_LEN; Index ++){
    9.         TxBufferPtr[Index] = 0x00;
    10.     }
    11.     CfgPtr = XAxiDma_LookupConfig(DMA_DEV_ID);
    12.     if (!CfgPtr) {
    13.         xil_printf("No config found for %d\r\n", DMA_DEV_ID);
    14.         return XST_FAILURE;
    15.     }
    16.     Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
    17.     if (Status != XST_SUCCESS) {
    18.         xil_printf("Initialization failed %d\r\n", Status);
    19.         return XST_FAILURE;
    20.     }
    21.     XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);
    22.     TxBufferPtr[0] = 0xef;
    23.     Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);
    24.     XAxiDma_Reset(&AxiDma);
    25.     Status = XAxiDma_MM2Stransfer(&AxiDma,(UINTPTR) TxBufferPtr, MAX_PKT_LEN);
    26.     if (Status != XST_SUCCESS){
    27.         xil_printf("XAXIDMA_DMA_TO_DEVICE transfer failed...\r\n");
    28.  return XST_FAILURE;
    29.     }
    30.     cleanup_platform();
    31.     return 0;
    32. }
    1840c4e4a752672229b04809c58d60c7.png

    测试设备

    为了验证模拟输出,将其通道 1 连接到示波器通道 1,并在主机 PC 上启动 WaveForms 来查看它。

    然后,在 Vitis 中启动 C 应用程序的调试,并在 MM2S 传输开始之前设置了断点:

    79ee256334f6ad022f0b9868356b23af.png

    由于将DAC设置为低增益模式,因此峰值输出值约为 1.0v。在 WaveForms 的 Scope 选项卡中,为超过 100mV 的上升沿设置电平触发器,然后单击Run 。

    得到 1 和 0 两个不同频率值的清晰输出:

    adb1d214826706c50685e0612e619b7f.png

    正如我上面提到的,这只是符号映射器的一个非常简化的版本,目的是为了以更实用、更实际的方式克服 SDR 设计入门的困难。两个不同频率的周期计数器是查看输出结果的良好起点。

    代码

    https://github.com/Digilent/vivado-boards

    https://github.com/suisuisi/FPGATechnologyGroup/tree/main/simple_2_fsk

  • 相关阅读:
    Jenkins配置linux节点
    CentOS断电丢失数据修复问题
    java日志框架之Logback和Log4j2
    GBASE 8s基本命令:onstat -k讲解
    目标检测YOLO实战应用案例100讲-基于卷积神经网络的小样本机载雷达动目标检测
    【算法每日一练]-旅行商(保姆级教程 篇1)
    软件安全学习课程实践3:软件漏洞利用实验
    LASSO回归
    Java语言中的异常处理
    appium+python自动化测试
  • 原文地址:https://blog.csdn.net/Pieces_thinking/article/details/132680536