From 2f89161c658c3580561a600ce4a32113514ca823 Mon Sep 17 00:00:00 2001 From: Niels Moseley Date: Sat, 21 Oct 2017 02:25:07 +0200 Subject: [PATCH] Added source and testbench --- verilog/source/run_tb.bat | 6 +++ verilog/source/source.v | 85 ++++++++++++++++++++++++++++++++++++++ verilog/source/source_tb.v | 66 +++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 verilog/source/run_tb.bat create mode 100644 verilog/source/source.v create mode 100644 verilog/source/source_tb.v diff --git a/verilog/source/run_tb.bat b/verilog/source/run_tb.bat new file mode 100644 index 0000000..1a81a5c --- /dev/null +++ b/verilog/source/run_tb.bat @@ -0,0 +1,6 @@ +mkdir bin +del bin\source.vvp +C:\iverilog\bin\iverilog -o bin\source.vvp -m va_math -g2005 -s SOURCE_TB source.v source_tb.v +cd bin +C:\iverilog\bin\vvp source.vvp -lxt2 +cd .. diff --git a/verilog/source/source.v b/verilog/source/source.v new file mode 100644 index 0000000..1d5f0fe --- /dev/null +++ b/verilog/source/source.v @@ -0,0 +1,85 @@ +// +// Source part of speech synth +// +// Niels Moseley - Moseley Instruments 2017 +// http://www.moseleyinstruments.com +// +// + +module SOURCE ( + clk, + rst_an, + period, // period in 10kHz samples + amplitude, // unsigned 15-bit desired amplitude of source output + strobe, // when strobe == '1' a new source_out will be generated + source_out // signed 16-bit source output + ); + + //////////// CLOCK ////////// + input clk; + + //////////// RESET, ACTIVE LOW ////////// + input rst_an; + + //////////// OUTPUTS ////////// + output reg signed [15:0] source_out; + + //////////// INPUTS ////////// + input [14:0] amplitude; + input [7:0] period; + input strobe; + + // internal counter and data registers + reg signed [7:0] periodcnt; + reg [16:0] lfsr; + + always @(posedge clk, negedge rst_an) + begin + if (rst_an == 0) + begin + // reset values + periodcnt <= 0; + source_out <= 0; + lfsr <= 17'h1; //note: never reset the LFSR to zero! + end + else + begin + if (strobe == 1) + begin + // if period == 0, we need to generate noise + // else we generate a pulse wave + if (period == 0) + begin + // ------------------------------------------------------------ + // LFSR NOISE GENERATOR + // ------------------------------------------------------------ + if (periodcnt == 64) + periodcnt <= 0; + else + periodcnt <= periodcnt + 1; + + // lfsr polynomial is X^17 + X^3 + 1 + lfsr = {lfsr[15:0], lfsr[16] ^ lfsr[2]}; + source_out <= lfsr[0] ? {2'b00, amplitude[14:1]} : {2'b11, (~amplitude[14:1])}; + end + else + begin + // ------------------------------------------------------------ + // PULSE GENERATOR + // ------------------------------------------------------------ + // make periodcnt count from 0 .. period-1 + if (periodcnt == period) + periodcnt <= 0; + else + periodcnt <= periodcnt + 1; + + if (periodcnt < 8) + source_out <= {1'b0, amplitude}; + else + source_out <= 16'h0000; + end + end + end + end + +endmodule diff --git a/verilog/source/source_tb.v b/verilog/source/source_tb.v new file mode 100644 index 0000000..8aca23e --- /dev/null +++ b/verilog/source/source_tb.v @@ -0,0 +1,66 @@ +// +// PWMDAC testbench +// +// Niels Moseley - Moseley Instruments 2017 +// http://www.moseleyinstruments.com +// + +module SOURCE_TB; + reg clk, rst_an, strobe; + reg signed [14:0] amp; + reg [7:0] period; + + reg [7:0] cnt; + + wire signed [15:0] source_out; + + SOURCE u_source ( + .clk (clk), + .rst_an (rst_an), + .period (period), + .amplitude (amp), + .strobe (strobe), + .source_out (source_out) + ); + + integer fd; // file descriptor + + initial + begin + fd = $fopen("audio.sw","wb"); + $dumpfile ("source.vcd"); + $dumpvars; + clk = 0; + rst_an = 0; + strobe = 0; + period = 50; + amp = 15000; + cnt = 0; + #3 + rst_an = 1; + #300000 + period = 0; // switch to noise mode + #300000 + $fclose(fd); + $finish; + end + + always @(posedge clk) + begin + if (cnt == 4) + begin + cnt <= 0; + strobe <= 1; + $fwrite(fd,"%u",{ {16{source_out[15]}} ,source_out}); + end + else + begin + strobe <= 0; + cnt <= cnt + 1; + end + end + + always + #5 clk = !clk; + +endmodule \ No newline at end of file