DDS直接数字合成2 - 任意信号

发布时间:2024-01-16  

为了生成任意信号, 依赖于两个主要技巧。

本文引用地址:

第一个 技巧是 (查找表)。 是一个表格,用于保存我们想要生成的模拟信号的形状。

在中,LUT是作为blockram实现的。 在上图中,我们使用了 512x10 位 LUT,它通常适合一个或两个物理 模块。

正弦波

最常产生的信号形状是正弦波。 它很特别,因为它有两个对称性,可以很容易地利用它们来使 LUT 看起来更大。

在正弦波中,第一个对称性是sin(α)=sin(π-α)。
假设我们的 “my__LUT” blockram 是这样实例化的

wire [9:0] LUT_output;

blockram512x10bit_2clklatency my_DDS_LUT(.rdclock(clk), .rdaddress(cnt[8:0]), .q(LUT_output));

我们只需要在半个周期后以相反的方向访问 LUT 即可利用第一个对称性。

blockram512x10bit_2clklatency my_DDS_LUT(.rdclock(clk), .rdaddress(cnt[9] ? ~cnt[8:0] : cnt[8:0]), .q(LUT_output));

因此,现在我们只将一半的波存储在模块中,但其内容在输出信号的每个周期中使用两次。 从某种意义上说,LUT 显示为 1024x10 位(使用第二种对称性,我们得到 2048x10 位)。

请注意,我们使用一个块“blockram512x10bit_2clklatency”,它提供具有两个时钟延迟的数据(因为一个时钟延迟块框速度较慢)。 如何做到这一点取决于供应商(Altera将使用LPM,而Xilinx将使用原语)。

让我们将 LUT 重写为一个单独的模块,利用两个正弦对称性。

// sine lookup value module using two symmetries
// appears like a 2048x10bit LUT even if it uses a 512x10bit internally
// 3 clock latencymodule sine_lookup(input clk, input [10:0] addr, output reg [16:0] value);
wire [15:0] sine_1sym;  // sine with 1 symmetry
blockram512x16bit_2clklatency my_quarter_sine_LUT(     // the LUT contains only one quarter of the sine wave
   .rdclock(clk),
   .rdaddress(addr[9] ? ~addr[8:0] : addr[8:0]),   // first symmetry
   .q(sine_1sym)
);

// now for the second symmetry, we need to use addr[10]
// but since our blockram has 2 clock latencies on reads
// we need a two-clock delayed version of addr[10]
reg addr10_delay1;
always @(posedge clk) addr10_delay1 <= addr[10];
reg addr10_delay2; always @(posedge clk) addr10_delay2 <= addr10_delay1;
wire [15:0] sine_2sym = addr10_delay2 ? {1'b0,-sine_1sym} : {1'b1,sine_1sym};  // second symmetry

// add a third latency to the module output for best performance
always @(posedge clk) value <= sine_2sym;
endmodule

请注意,sine_lookup模块总共有 3 个时钟延迟(两个来自模块,一个来自末尾的注册输出)。
时钟延迟的好处是可以流水线操作,并从FPGA中获得最大可能的性能。 不要忘记,这需要运行至少 100MHz。

此外,我们还将 blockram 的输出宽度从 10 位增加到 16 位(如果在我们的特定 FPGA 模块中未使用,则 6 位会丢失,因此我们不妨实现它们)。 我们将在第 4 部分中充分利用多余的部分。

为了有效地使用我们新制作的“sine_lookup模块”,我们可以简单地编写

reg [10:0] cnt;
always @(posedge clk) cnt <= cnt + 11'h1;
wire [16:0] sine_lookup_output;
sine_lookup my_sine(.clk(clk), .addr(cnt), .value(sine_lookup_output));
wire [9:0] DAC_data = sine_lookup_output[16:7];   // for now, we drop the LSBs to feed our DAC
                                                 // (since it takes only 10 bits)

我们从DAC得到一个很好的正弦波。

上一篇:

下一篇:

文章来源于:电子产品世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>