DDS module and test bench finished
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
// Detailed module description:
|
// Detailed module description:
|
||||||
//
|
//
|
||||||
// This module generete clk signal for
|
// 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 test is executed using Icarus Verilog!
|
||||||
//
|
//
|
||||||
// The result can be evaluated in GTKwave application.
|
// The result can be evaluated in GTKwave application.
|
||||||
|
|||||||
+33
-5
@@ -26,12 +26,40 @@ module dds_vhdl#( parameter
|
|||||||
output [phase_width - 1:0] phase_out,
|
output [phase_width - 1:0] phase_out,
|
||||||
output [data_width - 1:0] signal_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 (
|
lookuptable lookuptable (
|
||||||
.in(),
|
.phase( // mux
|
||||||
.out());
|
(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
|
endmodule
|
||||||
@@ -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
|
||||||
+44
-22
@@ -1,26 +1,48 @@
|
|||||||
module lookuptable(
|
module lookuptable #( parameter phase_width = 4, data_width = 8)(
|
||||||
input [7 :0] in,
|
input [phase_width - 1 :0] phase,
|
||||||
output reg [7 :0] out);
|
output reg [data_width - 1 :0] sin,
|
||||||
reg [7 :0] out = 8'h0;
|
output reg [data_width - 1 :0] cos);
|
||||||
always@* begin
|
always@* begin
|
||||||
case (in)
|
case (phase[phase_width - 1 : 0])
|
||||||
8'd0 : out <= 8'b00000000;
|
4'd0 : sin[data_width - 1 : 0] <= 8'b00000000;
|
||||||
8'd1 : out <= 8'b00011001;
|
4'd1 : sin[data_width - 1 : 0] <= 8'b00011001;
|
||||||
8'd2 : out <= 8'b00101101;
|
4'd2 : sin[data_width - 1 : 0] <= 8'b00101101;
|
||||||
8'd3 : out <= 8'b00111011;
|
4'd3 : sin[data_width - 1 : 0] <= 8'b00111011;
|
||||||
8'd4 : out <= 8'b01000000;
|
4'd4 : sin[data_width - 1 : 0] <= 8'b01000000;
|
||||||
8'd5 : out <= 8'b00111011;
|
4'd5 : sin[data_width - 1 : 0] <= 8'b00111011;
|
||||||
8'd6 : out <= 8'b00101101;
|
4'd6 : sin[data_width - 1 : 0] <= 8'b00101101;
|
||||||
8'd7 : out <= 8'b00011001;
|
4'd7 : sin[data_width - 1 : 0] <= 8'b00011001;
|
||||||
8'd8 : out <= 8'b00000000;
|
4'd8 : sin[data_width - 1 : 0] <= 8'b00000000;
|
||||||
8'd9 : out <= 8'b11101000;
|
4'd9 : sin[data_width - 1 : 0] <= 8'b11101000;
|
||||||
8'd10 : out <= 8'b11010011;
|
4'd10 : sin[data_width - 1 : 0] <= 8'b11010011;
|
||||||
8'd11 : out <= 8'b11000101;
|
4'd11 : sin[data_width - 1 : 0] <= 8'b11000101;
|
||||||
8'd12 : out <= 8'b11000000;
|
4'd12 : sin[data_width - 1 : 0] <= 8'b11000000;
|
||||||
8'd13 : out <= 8'b11000101;
|
4'd13 : sin[data_width - 1 : 0] <= 8'b11000101;
|
||||||
8'd14 : out <= 8'b11010011;
|
4'd14 : sin[data_width - 1 : 0] <= 8'b11010011;
|
||||||
8'd15 : out <= 8'b11101000;
|
4'd15 : sin[data_width - 1 : 0] <= 8'b11101000;
|
||||||
default : out <= 8'b00000000;
|
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
|
endcase
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
+44
-22
@@ -1,26 +1,48 @@
|
|||||||
module lookuptable(
|
module lookuptable #( parameter phase_width = 4, data_width = 8)(
|
||||||
input [7 :0] in,
|
input [phase_width - 1 :0] phase,
|
||||||
output reg [7 :0] out);
|
output reg [data_width - 1 :0] sin,
|
||||||
reg [7 :0] out = 8'h0;
|
output reg [data_width - 1 :0] cos);
|
||||||
always@* begin
|
always@* begin
|
||||||
case (in)
|
case (phase[phase_width - 1 : 0])
|
||||||
8'd0 : out <= 8'b00000000;
|
4'd0 : sin[data_width - 1 : 0] <= 8'b00000000;
|
||||||
8'd1 : out <= 8'b00011001;
|
4'd1 : sin[data_width - 1 : 0] <= 8'b00011001;
|
||||||
8'd2 : out <= 8'b00101101;
|
4'd2 : sin[data_width - 1 : 0] <= 8'b00101101;
|
||||||
8'd3 : out <= 8'b00111011;
|
4'd3 : sin[data_width - 1 : 0] <= 8'b00111011;
|
||||||
8'd4 : out <= 8'b01000000;
|
4'd4 : sin[data_width - 1 : 0] <= 8'b01000000;
|
||||||
8'd5 : out <= 8'b00111011;
|
4'd5 : sin[data_width - 1 : 0] <= 8'b00111011;
|
||||||
8'd6 : out <= 8'b00101101;
|
4'd6 : sin[data_width - 1 : 0] <= 8'b00101101;
|
||||||
8'd7 : out <= 8'b00011001;
|
4'd7 : sin[data_width - 1 : 0] <= 8'b00011001;
|
||||||
8'd8 : out <= 8'b00000000;
|
4'd8 : sin[data_width - 1 : 0] <= 8'b00000000;
|
||||||
8'd9 : out <= 8'b11101000;
|
4'd9 : sin[data_width - 1 : 0] <= 8'b11101000;
|
||||||
8'd10 : out <= 8'b11010011;
|
4'd10 : sin[data_width - 1 : 0] <= 8'b11010011;
|
||||||
8'd11 : out <= 8'b11000101;
|
4'd11 : sin[data_width - 1 : 0] <= 8'b11000101;
|
||||||
8'd12 : out <= 8'b11000000;
|
4'd12 : sin[data_width - 1 : 0] <= 8'b11000000;
|
||||||
8'd13 : out <= 8'b11000101;
|
4'd13 : sin[data_width - 1 : 0] <= 8'b11000101;
|
||||||
8'd14 : out <= 8'b11010011;
|
4'd14 : sin[data_width - 1 : 0] <= 8'b11010011;
|
||||||
8'd15 : out <= 8'b11101000;
|
4'd15 : sin[data_width - 1 : 0] <= 8'b11101000;
|
||||||
default : out <= 8'b00000000;
|
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
|
endcase
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
+36
-16
@@ -5,11 +5,11 @@
|
|||||||
% Module name - DDS (direct digital synthesis)
|
% Module name - DDS (direct digital synthesis)
|
||||||
%
|
%
|
||||||
% Detailed module description:
|
% Detailed module description:
|
||||||
% This file generates lock up table with SIN values
|
% This file generates lock up table with SIN and COS values
|
||||||
%
|
%
|
||||||
% Revision:
|
% Revision:
|
||||||
% A - initial design
|
% A - initial design
|
||||||
% B -
|
% B - add COS output
|
||||||
% C -
|
% C -
|
||||||
%
|
%
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
@@ -18,30 +18,50 @@ word_lenght = 8;
|
|||||||
table_size = 4; % 2^n
|
table_size = 4; % 2^n
|
||||||
x = linspace(0, (2*pi - 2*pi/2^table_size) , 2^table_size);
|
x = linspace(0, (2*pi - 2*pi/2^table_size) , 2^table_size);
|
||||||
sin_x = sin(x);
|
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
|
cos_x = cos(x);
|
||||||
hex = [];
|
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
|
for i=1:2^table_size
|
||||||
a = sfi(sin_x(i),word_lenght,word_lenght-2);
|
a = sfi(sin_x(i),word_lenght,word_lenght-2);
|
||||||
hex = [hex; a.bin];
|
b = sfi(cos_x(i),word_lenght,word_lenght-2);
|
||||||
|
hex_sin = [hex_sin; a.bin];
|
||||||
|
hex_cos = [hex_cos; b.bin];
|
||||||
end
|
end
|
||||||
hex,
|
%hex_sin,
|
||||||
|
%hex_cos,
|
||||||
|
|
||||||
fid = fopen('lookuptable.v', 'wt');
|
fid = fopen('lookuptable.v', 'wt');
|
||||||
fprintf(fid, 'module lookuptable(\n');
|
fprintf(fid, 'module lookuptable #( parameter phase_width = %d, data_width = %d)(\n', table_size, word_lenght);
|
||||||
fprintf(fid, '\tinput [%d :0] in,\n',word_lenght-1);
|
fprintf(fid, '\tinput [phase_width - 1 :0] phase,\n');
|
||||||
fprintf(fid, '\toutput reg [%d :0] out);\n',word_lenght-1);
|
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, 'always@* begin\n');
|
||||||
fprintf(fid, 'case (in)\n');
|
fprintf(fid, 'case (phase[phase_width - 1 : 0])\n');
|
||||||
|
|
||||||
for i=1:length(hex)
|
for i=1:length(hex_sin)
|
||||||
temp = hex(i,1:word_lenght);
|
temp = hex_sin(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) );
|
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
|
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, 'endcase\n');
|
||||||
fprintf(fid, 'end\n');
|
fprintf(fid, 'end\n');
|
||||||
fprintf(fid, 'endmodule');
|
fprintf(fid, 'endmodule');
|
||||||
|
|||||||
Reference in New Issue
Block a user