From 1598022c706c4f62ece90e7aa96298ecbe412dd0 Mon Sep 17 00:00:00 2001 From: Imants Pulkstenis Date: Wed, 1 Apr 2020 21:35:27 +0300 Subject: [PATCH] DDS module and test bench finished --- ps2/ps02q/ps02_tb.v | 2 +- ps4/dds_vhdl/dds_vhdl.v | 38 ++++++++++++++--- ps4/dds_vhdl/dds_vhdl_tb.v | 87 ++++++++++++++++++++++++++++++++++++++ ps4/dds_vhdl/lookuptable.v | 66 +++++++++++++++++++---------- ps4/lookuptable.v | 66 +++++++++++++++++++---------- ps4/table_gen.m | 54 +++++++++++++++-------- 6 files changed, 246 insertions(+), 67 deletions(-) create mode 100644 ps4/dds_vhdl/dds_vhdl_tb.v diff --git a/ps2/ps02q/ps02_tb.v b/ps2/ps02q/ps02_tb.v index 930aaee..aec8980 100644 --- a/ps2/ps02q/ps02_tb.v +++ b/ps2/ps02q/ps02_tb.v @@ -7,7 +7,7 @@ // Detailed module description: // // This module generete clk signal for -// for tom podule of ps02 project +// top module of ps02 project // The test is executed using Icarus Verilog! // // The result can be evaluated in GTKwave application. diff --git a/ps4/dds_vhdl/dds_vhdl.v b/ps4/dds_vhdl/dds_vhdl.v index a324873..e40da35 100644 --- a/ps4/dds_vhdl/dds_vhdl.v +++ b/ps4/dds_vhdl/dds_vhdl.v @@ -26,12 +26,40 @@ module dds_vhdl#( parameter output [phase_width - 1:0] phase_out, output [data_width - 1:0] signal_out); -// define inside of the module + + +reg [phase_width - 1:0] r_phase_incr = 'd0; +reg [phase_width - 1:0] r_phase_out = 'd0; + + +// Phase increment – determines output frequency +always@(posedge clk)begin + if (rst) begin + r_phase_incr <= 0; end + else begin + r_phase_incr <= phase_incr; end +end + +// Phase accumulator – the «counter» +always@(posedge clk)begin + if (rst) begin + r_phase_out <= 0; end + else begin + r_phase_out <= phase_out + phase_incr; end +end + +// Look-up table – memory where waveform is stored lookuptable lookuptable ( - .in(), - .out()); - - + .phase( // mux + (control== 0) ? 4'b0 : + (control== 1) ? {2'b0, phase_out[phase_width - 3:0] } : + (control== 2) ? {1'b0, phase_out[phase_width - 2:0] } : + phase_out + // end of MUX + ), + .sin(signal_out), + .cos()); +assign phase_out = r_phase_out; endmodule \ No newline at end of file diff --git a/ps4/dds_vhdl/dds_vhdl_tb.v b/ps4/dds_vhdl/dds_vhdl_tb.v new file mode 100644 index 0000000..ad1484c --- /dev/null +++ b/ps4/dds_vhdl/dds_vhdl_tb.v @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////// +// Author - Imants Pulkstenis +// Date - 01.04.2020 +// Project name - PS04 +// Module name - test bench of DDS (direct digital synthesis) +// +// Detailed module description: +// This module generete clk signal for +// top module of dds_vhdl project +// The test is executed using Icarus Verilog! +// +// The result can be evaluated in GTKwave application. +// Code: +// iverilog -o output.vvp dds_vhdl_tb.v && vvp output.vvp +// gtkwave -f wave.vcd +// +// Revision: +// A - initial design +// B - +// C - +// +/////////////////////////////////////////////////////////////////// + +//sub modules +`include "lookuptable.v" +//top module +`include "dds_vhdl.v" + + +//define module and connections to outside +module dds_vhdl_tb #( parameter + phase_width = 4, + data_width = 8 +)(); + +//define inside use signals + +reg clk = 1'b0; +reg rst = 1'b0; +reg [1:0] r_control = 'd3; +reg [phase_width - 1:0] r_phase_incr = 'd1; + +//---------Test script---------------- +// 50% duty cycle clock +always #0.5 clk <= ~clk; + +//-----Unit Under test--------------- +dds_vhdl #( + .data_width(8) +) unit_under_test ( + .clk(clk), + .rst(rst), + .control(r_control), + .phase_incr(r_phase_incr), + .phase_out(), + .signal_out() +); + + +//---------Test-------------------- +initial begin + rst = 1; + #10; + rst = 0; + #100 + r_control = 2; + #100 + r_control = 1; + #100 + r_control = 0; + #100 + $finish(); +end + +initial begin + $display(" "); + $display("----------------------------------------------"); + $display(" Starting Testbench..."); + $dumpfile("wave.vcd"); + $dumpvars(0); + $display("----------------------------------------------"); + $display(" "); +end + + + +endmodule \ No newline at end of file diff --git a/ps4/dds_vhdl/lookuptable.v b/ps4/dds_vhdl/lookuptable.v index d8191e2..270556f 100644 --- a/ps4/dds_vhdl/lookuptable.v +++ b/ps4/dds_vhdl/lookuptable.v @@ -1,26 +1,48 @@ -module lookuptable( - input [7 :0] in, - output reg [7 :0] out); -reg [7 :0] out = 8'h0; +module lookuptable #( parameter phase_width = 4, data_width = 8)( + input [phase_width - 1 :0] phase, + output reg [data_width - 1 :0] sin, + output reg [data_width - 1 :0] cos); always@* begin -case (in) - 8'd0 : out <= 8'b00000000; - 8'd1 : out <= 8'b00011001; - 8'd2 : out <= 8'b00101101; - 8'd3 : out <= 8'b00111011; - 8'd4 : out <= 8'b01000000; - 8'd5 : out <= 8'b00111011; - 8'd6 : out <= 8'b00101101; - 8'd7 : out <= 8'b00011001; - 8'd8 : out <= 8'b00000000; - 8'd9 : out <= 8'b11101000; - 8'd10 : out <= 8'b11010011; - 8'd11 : out <= 8'b11000101; - 8'd12 : out <= 8'b11000000; - 8'd13 : out <= 8'b11000101; - 8'd14 : out <= 8'b11010011; - 8'd15 : out <= 8'b11101000; - default : out <= 8'b00000000; +case (phase[phase_width - 1 : 0]) + 4'd0 : sin[data_width - 1 : 0] <= 8'b00000000; + 4'd1 : sin[data_width - 1 : 0] <= 8'b00011001; + 4'd2 : sin[data_width - 1 : 0] <= 8'b00101101; + 4'd3 : sin[data_width - 1 : 0] <= 8'b00111011; + 4'd4 : sin[data_width - 1 : 0] <= 8'b01000000; + 4'd5 : sin[data_width - 1 : 0] <= 8'b00111011; + 4'd6 : sin[data_width - 1 : 0] <= 8'b00101101; + 4'd7 : sin[data_width - 1 : 0] <= 8'b00011001; + 4'd8 : sin[data_width - 1 : 0] <= 8'b00000000; + 4'd9 : sin[data_width - 1 : 0] <= 8'b11101000; + 4'd10 : sin[data_width - 1 : 0] <= 8'b11010011; + 4'd11 : sin[data_width - 1 : 0] <= 8'b11000101; + 4'd12 : sin[data_width - 1 : 0] <= 8'b11000000; + 4'd13 : sin[data_width - 1 : 0] <= 8'b11000101; + 4'd14 : sin[data_width - 1 : 0] <= 8'b11010011; + 4'd15 : sin[data_width - 1 : 0] <= 8'b11101000; + default : sin[data_width - 1 : 0] <= 8'b00000000; + endcase +end + +always@* begin +case (phase[phase_width - 1 : 0]) + 4'd0 : cos[data_width - 1 : 0] <= 8'b01000000; + 4'd1 : cos[data_width - 1 : 0] <= 8'b00111011; + 4'd2 : cos[data_width - 1 : 0] <= 8'b00101101; + 4'd3 : cos[data_width - 1 : 0] <= 8'b00011001; + 4'd4 : cos[data_width - 1 : 0] <= 8'b00000000; + 4'd5 : cos[data_width - 1 : 0] <= 8'b11101000; + 4'd6 : cos[data_width - 1 : 0] <= 8'b11010011; + 4'd7 : cos[data_width - 1 : 0] <= 8'b11000101; + 4'd8 : cos[data_width - 1 : 0] <= 8'b11000000; + 4'd9 : cos[data_width - 1 : 0] <= 8'b11000101; + 4'd10 : cos[data_width - 1 : 0] <= 8'b11010011; + 4'd11 : cos[data_width - 1 : 0] <= 8'b11101000; + 4'd12 : cos[data_width - 1 : 0] <= 8'b00000000; + 4'd13 : cos[data_width - 1 : 0] <= 8'b00011001; + 4'd14 : cos[data_width - 1 : 0] <= 8'b00101101; + 4'd15 : cos[data_width - 1 : 0] <= 8'b00111011; + default : cos[data_width - 1 : 0] <= 8'b01000000; endcase end endmodule \ No newline at end of file diff --git a/ps4/lookuptable.v b/ps4/lookuptable.v index d8191e2..270556f 100644 --- a/ps4/lookuptable.v +++ b/ps4/lookuptable.v @@ -1,26 +1,48 @@ -module lookuptable( - input [7 :0] in, - output reg [7 :0] out); -reg [7 :0] out = 8'h0; +module lookuptable #( parameter phase_width = 4, data_width = 8)( + input [phase_width - 1 :0] phase, + output reg [data_width - 1 :0] sin, + output reg [data_width - 1 :0] cos); always@* begin -case (in) - 8'd0 : out <= 8'b00000000; - 8'd1 : out <= 8'b00011001; - 8'd2 : out <= 8'b00101101; - 8'd3 : out <= 8'b00111011; - 8'd4 : out <= 8'b01000000; - 8'd5 : out <= 8'b00111011; - 8'd6 : out <= 8'b00101101; - 8'd7 : out <= 8'b00011001; - 8'd8 : out <= 8'b00000000; - 8'd9 : out <= 8'b11101000; - 8'd10 : out <= 8'b11010011; - 8'd11 : out <= 8'b11000101; - 8'd12 : out <= 8'b11000000; - 8'd13 : out <= 8'b11000101; - 8'd14 : out <= 8'b11010011; - 8'd15 : out <= 8'b11101000; - default : out <= 8'b00000000; +case (phase[phase_width - 1 : 0]) + 4'd0 : sin[data_width - 1 : 0] <= 8'b00000000; + 4'd1 : sin[data_width - 1 : 0] <= 8'b00011001; + 4'd2 : sin[data_width - 1 : 0] <= 8'b00101101; + 4'd3 : sin[data_width - 1 : 0] <= 8'b00111011; + 4'd4 : sin[data_width - 1 : 0] <= 8'b01000000; + 4'd5 : sin[data_width - 1 : 0] <= 8'b00111011; + 4'd6 : sin[data_width - 1 : 0] <= 8'b00101101; + 4'd7 : sin[data_width - 1 : 0] <= 8'b00011001; + 4'd8 : sin[data_width - 1 : 0] <= 8'b00000000; + 4'd9 : sin[data_width - 1 : 0] <= 8'b11101000; + 4'd10 : sin[data_width - 1 : 0] <= 8'b11010011; + 4'd11 : sin[data_width - 1 : 0] <= 8'b11000101; + 4'd12 : sin[data_width - 1 : 0] <= 8'b11000000; + 4'd13 : sin[data_width - 1 : 0] <= 8'b11000101; + 4'd14 : sin[data_width - 1 : 0] <= 8'b11010011; + 4'd15 : sin[data_width - 1 : 0] <= 8'b11101000; + default : sin[data_width - 1 : 0] <= 8'b00000000; + endcase +end + +always@* begin +case (phase[phase_width - 1 : 0]) + 4'd0 : cos[data_width - 1 : 0] <= 8'b01000000; + 4'd1 : cos[data_width - 1 : 0] <= 8'b00111011; + 4'd2 : cos[data_width - 1 : 0] <= 8'b00101101; + 4'd3 : cos[data_width - 1 : 0] <= 8'b00011001; + 4'd4 : cos[data_width - 1 : 0] <= 8'b00000000; + 4'd5 : cos[data_width - 1 : 0] <= 8'b11101000; + 4'd6 : cos[data_width - 1 : 0] <= 8'b11010011; + 4'd7 : cos[data_width - 1 : 0] <= 8'b11000101; + 4'd8 : cos[data_width - 1 : 0] <= 8'b11000000; + 4'd9 : cos[data_width - 1 : 0] <= 8'b11000101; + 4'd10 : cos[data_width - 1 : 0] <= 8'b11010011; + 4'd11 : cos[data_width - 1 : 0] <= 8'b11101000; + 4'd12 : cos[data_width - 1 : 0] <= 8'b00000000; + 4'd13 : cos[data_width - 1 : 0] <= 8'b00011001; + 4'd14 : cos[data_width - 1 : 0] <= 8'b00101101; + 4'd15 : cos[data_width - 1 : 0] <= 8'b00111011; + default : cos[data_width - 1 : 0] <= 8'b01000000; endcase end endmodule \ No newline at end of file diff --git a/ps4/table_gen.m b/ps4/table_gen.m index fe90fb7..f548e28 100644 --- a/ps4/table_gen.m +++ b/ps4/table_gen.m @@ -5,11 +5,11 @@ % Module name - DDS (direct digital synthesis) % % Detailed module description: -% This file generates lock up table with SIN values +% This file generates lock up table with SIN and COS values % % Revision: % A - initial design -% B - +% B - add COS output % C - % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -18,30 +18,50 @@ word_lenght = 8; table_size = 4; % 2^n x = linspace(0, (2*pi - 2*pi/2^table_size) , 2^table_size); sin_x = sin(x); -sin_x = round(sin_x * 2^word_lenght) / 2^word_lenght; +sin_x = round(sin_x * 2^word_lenght) / 2^word_lenght; % round values -%% Print values in hex -hex = []; +cos_x = cos(x); +cos_x = round(cos_x * 2^word_lenght) / 2^word_lenght; % round values + +%% Print values in HEX +hex_sin = []; +hex_cos = []; for i=1:2^table_size - a = sfi(sin_x(i),word_lenght,word_lenght-2); - hex = [hex; a.bin]; + a = sfi(sin_x(i),word_lenght,word_lenght-2); + b = sfi(cos_x(i),word_lenght,word_lenght-2); + hex_sin = [hex_sin; a.bin]; + hex_cos = [hex_cos; b.bin]; end -hex, +%hex_sin, +%hex_cos, fid = fopen('lookuptable.v', 'wt'); - fprintf(fid, 'module lookuptable(\n'); - fprintf(fid, '\tinput [%d :0] in,\n',word_lenght-1); - fprintf(fid, '\toutput reg [%d :0] out);\n',word_lenght-1); + fprintf(fid, 'module lookuptable #( parameter phase_width = %d, data_width = %d)(\n', table_size, word_lenght); + fprintf(fid, '\tinput [phase_width - 1 :0] phase,\n'); + fprintf(fid, '\toutput reg [data_width - 1 :0] sin,\n'); + fprintf(fid, '\toutput reg [data_width - 1 :0] cos);\n'); - fprintf(fid, 'reg [%d :0] out = %d''h0; \n', word_lenght-1,word_lenght); +% fprintf(fid, 'reg [%d :0] sin = %d''h0; \n', word_lenght-1,word_lenght); fprintf(fid, 'always@* begin\n'); - fprintf(fid, 'case (in)\n'); + fprintf(fid, 'case (phase[phase_width - 1 : 0])\n'); -for i=1:length(hex) - temp = hex(i,1:word_lenght); - fprintf(fid, '\t%d''d%d : out <= %d''b%s;\n',word_lenght, i-1 ,word_lenght, hex(i,1:word_lenght) ); +for i=1:length(hex_sin) + temp = hex_sin(i,1:word_lenght); + fprintf(fid, '\t%d''d%d : sin[data_width - 1 : 0] <= %d''b%s;\n',table_size, i-1 ,word_lenght, hex_sin(i,1:word_lenght) ); end - fprintf(fid, '\tdefault : out <= %d''b%s;\n ',word_lenght, hex(1,1:word_lenght) ); + fprintf(fid, '\tdefault : sin[data_width - 1 : 0] <= %d''b%s;\n ',word_lenght, hex_sin(1,1:word_lenght) ); + fprintf(fid, 'endcase\n'); + fprintf(fid, 'end\n'); + fprintf(fid, ' \n'); + + fprintf(fid, 'always@* begin\n'); + fprintf(fid, 'case (phase[phase_width - 1 : 0])\n'); + +for i=1:length(hex_cos) + temp = hex_cos(i,1:word_lenght); + fprintf(fid, '\t%d''d%d : cos[data_width - 1 : 0] <= %d''b%s;\n',table_size, i-1 , word_lenght, hex_cos(i,1:word_lenght) ); +end + fprintf(fid, '\tdefault : cos[data_width - 1 : 0] <= %d''b%s;\n ',word_lenght, hex_cos(1,1:word_lenght) ); fprintf(fid, 'endcase\n'); fprintf(fid, 'end\n'); fprintf(fid, 'endmodule');