// // // This is just a little demo of DDS. It doesn't have any cool features // or anything.. // module dds ( clk, reset, din, dout ); parameter W = 12; input clk; // Primary clock. input reset; // Synchronous reset. input [W-1:0] din; // The "phase step". output [W-1:0] dout; // Output of the phase accumulator register. reg [W-1:0] dout; reg [W-1:0] accum; // Phas Accumulator // Just output the accumulator... always @(accum) dout <= accum; // Specify the accumulator.. always @(posedge clk) begin if (reset) accum <= 0; else begin accum <= accum + din; end end endmodule // synopsys translate_off module ddstest; reg clk; reg reset; reg [11:0] din; wire [11:0] dout; reg [7:0] cosout; // Instantiate the DDS with 12-bits. // dds #(12) dds1 (.clk(clk), .reset(reset), .din(din), .dout(dout)); // Here's our Cosine lookup table. // reg [7:0] costable[0:4095]; // 4KBytes. // DDS Phase Accumulator output simply indexes into the Cos lookup table. // always @(dout) cosout <= costable[dout]; // Main test thread. // initial begin $readmemh ("cos.hex", costable); // See the PERL program 'generate_cos_table.pl' din = 12'h020; // Start at 16 #500000; din = 12'h0D0; // A little faster.. #500000; din = 12'h200; // Fairly fast. #500000; $finish; end // Let's clock it at 1 MHz initial begin clk = 0; forever begin #500 clk = 1; #500 clk = 0; end end // Reset initial begin reset = 1; #3500 reset = 0; end // Generate VCD file for viewing. initial begin $dumpfile ("dds.vcd"); $dumpvars (0,ddstest); end endmodule /* //*** Here's the Perl program for your reference... `ifdef WHEN_PERL_IS_A_SUBSET_OF_VERILOG #!/tools2/perl/bin/perl # # Generate a file of cos data for use by a DDS simulation. # $n = 4096; # Number of data points $minval = 0; # Smallest cos value. $maxval = 255; # Largest cos value. $pi = 3.1415927; $t = 0; for ($i = 1; $i < $n; $i = $i + 1) { $value = ($maxval - $minval)/2 + (($maxval - $minval)/2)*cos($t); $value = int($value); printf "%x\n", $value; $t = $t + 2*$pi / $n; } `endif */