/ 9_Firmware / 9_2_FPGA / dac_interface_single.v
dac_interface_single.v
 1  module dac_interface_enhanced (
 2      input wire clk_120m,
 3      input wire reset_n,
 4      input wire [7:0] chirp_data,
 5      input wire chirp_valid,
 6      output wire [7:0] dac_data,
 7      output wire dac_clk,
 8      output wire dac_sleep
 9  );
10  
11  // ============================================================================
12  // DAC data register (fabric FF — feeds ODDR D1/D2 inputs)
13  // ============================================================================
14  reg [7:0] dac_data_reg;
15  
16  always @(posedge clk_120m or negedge reset_n) begin
17      if (!reset_n) begin
18          dac_data_reg <= 8'd128;  // Center value
19      end else if (chirp_valid) begin
20          dac_data_reg <= chirp_data;
21      end else begin
22          dac_data_reg <= 8'd128;  // Default to center when no chirp
23      end
24  end
25  
26  `ifndef SIMULATION
27  // ============================================================================
28  // ODDR for dac_clk forwarding (Xilinx 7-series)
29  // D1=1, D2=0 produces a clock replica aligned to clk_120m rising edge.
30  // The ODDR is placed in the IOB, giving near-zero skew between the
31  // forwarded clock and ODDR data outputs in the same bank.
32  // ============================================================================
33  ODDR #(
34      .DDR_CLK_EDGE("OPPOSITE_EDGE"),
35      .INIT(1'b0),
36      .SRTYPE("SYNC")
37  ) oddr_dac_clk (
38      .Q(dac_clk),
39      .C(clk_120m),
40      .CE(1'b1),
41      .D1(1'b1),
42      .D2(1'b0),
43      .R(1'b0),
44      .S(1'b0)
45  );
46  
47  // ============================================================================
48  // ODDR for dac_data[7:0] — packs output FFs into IOBs
49  // D1=D2=same value → SDR behavior through ODDR, but placed in IOB.
50  // This eliminates fabric routing delay to the output pad.
51  // ============================================================================
52  genvar i;
53  generate
54      for (i = 0; i < 8; i = i + 1) begin : oddr_dac_data_gen
55          ODDR #(
56              .DDR_CLK_EDGE("OPPOSITE_EDGE"),
57              .INIT(1'b0),
58              .SRTYPE("SYNC")
59          ) oddr_dac_data (
60              .Q(dac_data[i]),
61              .C(clk_120m),
62              .CE(1'b1),
63              .D1(dac_data_reg[i]),
64              .D2(dac_data_reg[i]),
65              .R(1'b0),
66              .S(1'b0)
67          );
68      end
69  endgenerate
70  
71  `else
72  // ============================================================================
73  // Simulation behavioral equivalent
74  // ============================================================================
75  assign dac_clk = clk_120m;
76  assign dac_data = dac_data_reg;
77  `endif
78  
79  assign dac_sleep = 1'b0;
80  
81  endmodule