dds.v 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. `timescale 1 ns / 1 ps
  2. module dds #
  3. (
  4. parameter NEGATIVE_SINE = "FALSE"
  5. )
  6. (
  7. input wire aclk,
  8. input wire aresetn,
  9. input wire [31:0] pinc,
  10. output wire [47:0] dout
  11. );
  12. reg [31:0] int_cntr_reg;
  13. reg [23:0] int_cos_reg, int_sin_reg;
  14. reg [10:0] int_addr_reg;
  15. reg [1:0] int_sign_reg [2:0];
  16. wire [47:0] int_p_wire [2:0];
  17. wire [31:0] int_cntr_wire;
  18. wire [29:0] int_cos_wire, int_sin_wire;
  19. wire [22:0] int_lut_wire [1:0];
  20. wire [17:0] int_corr_wire;
  21. wire [2:0] int_pbd_wire;
  22. assign int_cos_wire = int_sign_reg[2][0] ? {7'h7f, -int_lut_wire[0]} : {7'h00, int_lut_wire[0]};
  23. assign int_sin_wire = int_sign_reg[2][1] ? {7'h7f, -int_lut_wire[1]} : {7'h00, int_lut_wire[1]};
  24. assign int_corr_wire = {int_p_wire[0][34:18], int_p_wire[0][17] | int_pbd_wire[0]};
  25. generate
  26. if(NEGATIVE_SINE == "TRUE")
  27. begin : NEGATIVE
  28. assign int_cntr_wire = int_cntr_reg - pinc;
  29. end
  30. else
  31. begin : POSITIVE
  32. assign int_cntr_wire = int_cntr_reg + pinc;
  33. end
  34. endgenerate
  35. always @(posedge aclk)
  36. begin
  37. if(~aresetn)
  38. begin
  39. int_cntr_reg <= 32'd0;
  40. int_cos_reg <= 24'd0;
  41. int_sin_reg <= 24'd0;
  42. int_addr_reg <= 11'd0;
  43. int_sign_reg[0] <= 2'd0;
  44. int_sign_reg[1] <= 2'd0;
  45. int_sign_reg[2] <= 2'd0;
  46. end
  47. else
  48. begin
  49. int_cntr_reg <= int_cntr_wire;
  50. int_cos_reg <= int_cos_wire[23:0];
  51. int_sin_reg <= int_sin_wire[23:0];
  52. int_addr_reg <= int_cntr_reg[29:19];
  53. int_sign_reg[0] <= {int_cntr_reg[31], int_cntr_reg[30]};
  54. int_sign_reg[1] <= {int_sign_reg[0][1], int_sign_reg[0][1] ^ int_sign_reg[0][0]};
  55. int_sign_reg[2] <= int_sign_reg[1];
  56. end
  57. end
  58. xpm_memory_dprom #(
  59. .MEMORY_PRIMITIVE("block"),
  60. .MEMORY_SIZE(47104),
  61. .ADDR_WIDTH_A(11),
  62. .ADDR_WIDTH_B(11),
  63. .READ_DATA_WIDTH_A(23),
  64. .READ_DATA_WIDTH_B(23),
  65. .READ_LATENCY_A(2),
  66. .READ_LATENCY_B(2),
  67. .MEMORY_INIT_PARAM(""),
  68. .MEMORY_INIT_FILE("dds.mem")
  69. ) rom_0 (
  70. .clka(aclk),
  71. .clkb(aclk),
  72. .rsta(1'b0),
  73. .rstb(1'b0),
  74. .ena(1'b1),
  75. .enb(1'b1),
  76. .regcea(1'b1),
  77. .regceb(1'b1),
  78. .addra(int_sign_reg[0][0] ? ~int_addr_reg : int_addr_reg),
  79. .addrb(int_sign_reg[0][0] ? int_addr_reg : ~int_addr_reg),
  80. .douta(int_lut_wire[0]),
  81. .doutb(int_lut_wire[1])
  82. );
  83. DSP48E1 #(
  84. .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
  85. .BREG(0), .BCASCREG(0), .CREG(0), .CARRYINREG(0),
  86. .USE_PATTERN_DETECT("PATDET"), .MASK(48'hfffffffe0000)
  87. ) dsp_0 (
  88. .CLK(aclk),
  89. .RSTA(1'b0), .RSTM(1'b0), .RSTP(1'b0),
  90. .CEA2(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
  91. .ALUMODE(4'b0000), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
  92. .A({{(12){~int_cntr_reg[18]}}, int_cntr_reg[17:0]}),
  93. .B(18'd3217),
  94. .C(48'hffff),
  95. .CARRYIN(1'b0),
  96. .PATTERNBDETECT(int_pbd_wire[0]),
  97. .P(int_p_wire[0])
  98. );
  99. DSP48E1 #(
  100. .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
  101. .CARRYINREG(0),
  102. .USE_PATTERN_DETECT("PATDET"), .MASK(48'hffffff000000)
  103. ) dsp_1 (
  104. .CLK(aclk),
  105. .RSTA(1'b0), .RSTB(1'b0), .RSTC(1'b0), .RSTM(1'b0), .RSTP(1'b0),
  106. .CEA2(1'b1), .CEB2(1'b1), .CEC(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
  107. .ALUMODE(4'b0011), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
  108. .A(int_sin_wire),
  109. .B(int_corr_wire),
  110. .C({int_cos_reg, 24'h7fffff}),
  111. .CARRYIN(1'b0),
  112. .PATTERNBDETECT(int_pbd_wire[1]),
  113. .P(int_p_wire[1])
  114. );
  115. DSP48E1 #(
  116. .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
  117. .CARRYINREG(0),
  118. .USE_PATTERN_DETECT("PATDET"), .MASK(48'hffffff000000)
  119. ) dsp_2 (
  120. .CLK(aclk),
  121. .RSTA(1'b0), .RSTB(1'b0), .RSTC(1'b0), .RSTM(1'b0), .RSTP(1'b0),
  122. .CEA2(1'b1), .CEB2(1'b1), .CEC(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
  123. .ALUMODE(4'b0000), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
  124. .A(int_cos_wire),
  125. .B(int_corr_wire),
  126. .C({int_sin_reg, 24'h7fffff}),
  127. .CARRYIN(1'b0),
  128. .PATTERNBDETECT(int_pbd_wire[2]),
  129. .P(int_p_wire[2])
  130. );
  131. assign dout = {int_p_wire[2][47:25], int_p_wire[2][24] | int_pbd_wire[2], int_p_wire[1][47:25], int_p_wire[1][24] | int_pbd_wire[1]};
  132. endmodule