// // // 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 */ [ [ ['module', 'dds', '(', [['clk'], ['reset'], ['din'], ['dout']], ')', ';'], [ ['parameter', ['W', '=', '12'], ';'], ['input', 'clk', ';'], ['input', 'reset', ';'], ['input', '[', ['W'], '-', '1', ':', '0', ']', 'din', ';'], ['output', '[', ['W'], '-', '1', ':', '0', ']', 'dout', ';'], ['reg', '[', ['W'], '-', '1', ':', '0', ']', ['dout'], ';'], ['reg', '[', ['W'], '-', '1', ':', '0', ']', ['accum'], ';'], [ 'always', ['@', '(', [['accum']], ')'], [[['dout'], '<=', ['accum']], ';']], [ 'always', ['@', '(', ['posedge', ['clk']], ')'], [ 'begin', [ [ 'if', ['(', ['reset'], ')'], [[['accum'], '<=', '0'], ';'], 'else', [ 'begin', [[[['accum'], '<=', ['accum'], '+', ['din']], ';']], 'end']]], 'end']]], 'endmodule'], [ ['module', 'ddstest', ';'], [ ['reg', ['clk'], ';'], ['reg', ['reset'], ';'], ['reg', '[', '11', ':', '0', ']', ['din'], ';'], ['wire', '[', '11', ':', '0', ']', ['dout'], ';'], ['reg', '[', '7', ':', '0', ']', ['cosout'], ';'], [ 'dds', ['#', '(', ['12'], ')'], [ ['dds1'], [ '(', ['.', 'clk', '(', ['clk'], ')'], ['.', 'reset', '(', ['reset'], ')'], ['.', 'din', '(', ['din'], ')'], ['.', 'dout', '(', ['dout'], ')'], ')']], ';'], [ 'reg', '[', '7', ':', '0', ']', ['costable', '[', '0', ':', '4095', ']'], ';'], [ 'always', ['@', '(', [['dout']], ')'], [[['cosout'], '<=', ['costable', ['[', ['dout'], ']']]], ';']], [ 'initial', [ 'begin', [ ['$readmemh', '(', '"cos.hex"', ['costable'], ')', ';'], [[['din'], '=', "12 'h 020"], ';'], [['#', '500000'], ';'], [[['din'], '=', "12 'h 0D0"], ';'], [['#', '500000'], ';'], [[['din'], '=', "12 'h 200"], ';'], [['#', '500000'], ';'], ['$finish', ';']], 'end']], [ 'initial', [ 'begin', [ [[['clk'], '=', '0'], ';'], [ 'forever', [ 'begin', [ [['#', '500'], [[['clk'], '=', '1'], ';']], [['#', '500'], [[['clk'], '=', '0'], ';']]], 'end']]], 'end']], [ 'initial', [ 'begin', [ [[['reset'], '=', '1'], ';'], [['#', '3500'], [[['reset'], '=', '0'], ';']]], 'end']], [ 'initial', [ 'begin', [ ['$dumpfile', '(', '"dds.vcd"', ')', ';'], ['$dumpvars', '(', '0', ['ddstest'], ')', ';']], 'end']]], 'endmodule']]