1

我正在编写代码来与这个DAC 接口以产生正弦波。我有一个可以很好地生成值的正弦 LUT,以及一个 DAC 控制器。控制器将 CS 拉低,逐位输入 16 位整数,并在 16 次计数后将 CS 拉高。当它发出脉冲时,它还会向 sin LUT 发送一个使能脉冲,以增加一个数字。这段代码似乎不能很好地工作,因为我的输出出现了峰值。这是因为时钟在本应为高时读取 CS 为低(图 1),导致 DAC 读取 17 位(即,将当前数字的 MSB 读取为前一个数字的 LSB),这导致尴尬尖峰(图 2)。

我怎样才能更好地组织这段代码,以便最大限度地减少遇到这个时间问题的风险?

module DAC_Control(
  input [15:0]data_in,
  input counter_enable,
  input clk,
  input rst,
  output data_out,
  output reg cs,
  output reg enable
  );

//bit counter
  reg [3:0] bit_counter;

//to help with shifting
  reg [15:0] shifter;

//shifter
  always @(posedge (clk)) begin
    if (rst) begin
      bit_counter <= 4'b0;
      shifter <= 0;
      end
    else if (counter_enable == 1) begin
        shifter <= data_in;
        bit_counter <= 4'b0;
    end
    else begin
      shifter <= shifter << 1; // shifting
      bit_counter <= bit_counter + 1'b1; // counter
    end
  end

  reg cs_hold;

  always @(posedge (clk)) begin
    if (rst) begin
      enable <= 1'b0;
      cs <= 1'b1;
      end
    else if (bit_counter == 4'b1110) begin
      enable <= 1'b1;
      cs <= 1'b0;
    end
    else if (bit_counter == 4'b1111) begin
      enable <= 1'b0;
      cs <= 1'b1;
    end
    else if (cs_hold == 1) begin
      enable <= 1'b0;
      cs <= 1'b1;
    end
    else begin
      enable <= 1'b0; // generate enable signals
      cs <= 1'b0;
    end
  end


  assign data_out = shifter[15];

endmodule

图 1. 黄色是 DIN,蓝色是 CS,绿色是时钟

图1

图 2. DAC 的输出

图 2

4

2 回答 2

2

DAC 使用上升沿对数据进行采样:

http://www.analog.com/media/en/technical-documentation/data-sheets/AD5541A.pdf

Serial Data Input. This device accepts 16-bit words. Data is clocked into the serial input register on the rising edge of SCLK.  

您可能想尝试在 clk 的下降沿生成 data_out 和 cs。

于 2016-08-17T19:28:11.357 回答
2

我不知道您的 FPGA 来自哪个供应商,但是,大多数都有时序约束,允许您定义时钟和数据之间的关系。他们使用虚拟时钟的想法。把它想象成有一个外部时钟,你可以说出时钟之间的差异。如果时钟是直接从 FPGA 生成的,而不是来自某些外部源,我认为您可以将一些 CLKs 值设置为 0。

通过设置这些类型的约束,您可以使数据输出相对于 clk 移动,并且它将是“一致且受控的”。

+----------+                +--------+
| FPGA     |----Data_out--->|  DAC   |
+----------+                +--------+
     CLKs /\               CLKd /\
          |                      |
          +-------sys_clk--------+

这是使用 SDC 对输出进行计时的 Altera 器件的解决方案。

#specify the maximum external clock delay to the FPGA
set CLKs_max 0.200
#specify the minimum external clock delay to the FPGA
set CLKs_min 0.100
#specify the maximum external clock delay to the external device
set CLKd_max 0.200
#specify the minimum external clock delay to the external device
set CLKd_min 0.100
#specify the maximum setup time of the external device
set tSU 0.125
#specify the minimum setup time of the external device
set tH 0.100
#specify the maximum board delay
set BD_max 0.180
#specify the minimum board delay
set BD_min 0.120
#create a clock 10ns
create_clock -period 10 -name sys_clk [get_ports sys_clk]
#create the associated virtual input clock
create_clock -period 10 -name virt_sys_clk
#create the output maximum delay for the data output from the FPGA that
#accounts for all delays specified
set_output_delay -clock virt_sys_clk \
    -max [expr $CLKs_max + $BD_max + $tSU - $CLKd_min] \
    [get_ports {data_out[*]}]
#create the output minimum delay for the data output from the FPGA that
#accounts for all delays specified
set_output_delay -clock virt_sys_clk \
    -min [expr $CLKs_min + $BD_min - $tH - $CLKd_max] \
    [get_ports {data_out[*]}]

或者,如果您不能通过约束来控制数据和时钟之间的关系,这似乎很俗气(如果是真的,请告诉我供应商,这样我就可以远离他们),您可以按照以下建议使情况变得更好上一个答案,通过将您的 posedge 更改为 negedge。请记住,这在构建之间可能是灵活的,因为输出可能不会按照您想要的方式受到限制。

于 2016-08-18T02:32:16.700 回答