dac.v 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 19:26:11 07/23/2010
  7. // Design Name:
  8. // Module Name: dac_test
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module dac(
  22. input clkin,
  23. input sysclk,
  24. input we,
  25. input[10:0] pgm_address,
  26. input[7:0] pgm_data,
  27. input play,
  28. input reset,
  29. output sdout,
  30. output lrck,
  31. output mclk,
  32. output DAC_STATUS
  33. );
  34. reg[8:0] dac_address_r;
  35. wire[8:0] dac_address = dac_address_r;
  36. wire[31:0] dac_data;
  37. assign DAC_STATUS = dac_address_r[8];
  38. reg[7:0] vol_reg;
  39. reg[7:0] vol_target_reg;
  40. reg[1:0] vol_latch_reg;
  41. reg vol_valid;
  42. reg[2:0] sysclk_sreg;
  43. wire sysclk_rising = (sysclk_sreg[2:1] == 2'b01);
  44. reg [25:0] interpol_count;
  45. always @(posedge clkin) begin
  46. sysclk_sreg <= {sysclk_sreg[1:0], sysclk};
  47. end
  48. dac_buf snes_dac_buf (
  49. .clka(clkin),
  50. .wea(~we), // Bus [0 : 0]
  51. .addra(pgm_address), // Bus [10 : 0]
  52. .dina(pgm_data), // Bus [7 : 0]
  53. .clkb(clkin),
  54. .addrb(dac_address), // Bus [8 : 0]
  55. .doutb(dac_data)); // Bus [31 : 0]
  56. reg [8:0] cnt;
  57. reg [15:0] smpcnt;
  58. reg [1:0] samples;
  59. reg [15:0] smpshift;
  60. assign mclk = cnt[2]; // mclk = clk/8
  61. assign lrck = cnt[8]; // lrck = mclk/128
  62. wire sclk = cnt[3]; // sclk = lrck*32
  63. reg [2:0] lrck_sreg;
  64. reg [2:0] sclk_sreg;
  65. wire lrck_rising = ({lrck_sreg[2:1]} == 2'b01);
  66. wire lrck_falling = ({lrck_sreg[2:1]} == 2'b10);
  67. wire sclk_rising = ({sclk_sreg[2:1]} == 2'b01);
  68. reg sdout_reg;
  69. assign sdout = sdout_reg;
  70. reg [1:0] reset_sreg;
  71. wire reset_rising = (reset_sreg[1:0] == 2'b01);
  72. reg play_r;
  73. initial begin
  74. cnt = 9'h100;
  75. smpcnt = 16'b0;
  76. lrck_sreg = 2'b11;
  77. sclk_sreg = 1'b0;
  78. dac_address_r = 10'b0;
  79. vol_valid = 1'b0;
  80. vol_latch_reg = 1'b0;
  81. vol_reg = 8'h0;
  82. vol_target_reg = 8'hff;
  83. samples <= 2'b00;
  84. end
  85. always @(posedge clkin) begin
  86. if(reset_rising) begin
  87. dac_address_r <= 0;
  88. interpol_count <= 0;
  89. end else if(sysclk_rising) begin
  90. if(interpol_count > 59378938) begin
  91. interpol_count <= interpol_count + 122500 - 59501439;
  92. dac_address_r <= dac_address_r + play_r;
  93. end else begin
  94. interpol_count <= interpol_count + 122500;
  95. end
  96. end
  97. end
  98. always @(posedge clkin) begin
  99. cnt <= cnt + 1;
  100. lrck_sreg <= {lrck_sreg[1:0], lrck};
  101. sclk_sreg <= {sclk_sreg[1:0], sclk};
  102. play_r <= play;
  103. reset_sreg <= {reset_sreg[0], reset};
  104. end
  105. // ramp volume only every 4 samples
  106. always @(posedge clkin) begin
  107. if (lrck_rising && &samples[1:0]) begin
  108. if(vol_reg > vol_target_reg)
  109. vol_reg <= vol_reg - 1;
  110. else if(vol_reg < vol_target_reg)
  111. vol_reg <= vol_reg + 1;
  112. end
  113. end
  114. always @(posedge clkin) begin
  115. if (lrck_rising) begin // right channel
  116. smpshift <= (({16'h0, dac_data[31:16]^16'h8000} * vol_reg) >> 8) ^ 16'h8000;
  117. samples <= samples + 1;
  118. end else if (lrck_falling) begin // left channel
  119. smpshift <= (({16'h0, dac_data[15:0]^16'h8000} * vol_reg) >> 8) ^ 16'h8000;
  120. end else begin
  121. if (sclk_rising) begin
  122. smpcnt <= smpcnt + 1;
  123. sdout_reg <= smpshift[15];
  124. smpshift <= {smpshift[14:0], 1'b0};
  125. end
  126. end
  127. end
  128. endmodule