First working simulation of 'hello, world' :)

This commit is contained in:
Niels Moseley 2017-10-24 21:49:05 +02:00
parent 31163effd9
commit 10d9735e11
7 changed files with 108 additions and 42 deletions

View File

@ -16,6 +16,7 @@ module CONTROLLER (
amp_out, // amplitude output amp_out, // amplitude output
coeff_out, // 8-bit coefficient data out coeff_out, // 8-bit coefficient data out
coeff_stb, // '1' when coeff_out holds new coefficient data coeff_stb, // '1' when coeff_out holds new coefficient data
clear_states, // outputs '1' to reset filter states
period_done_in // should be '1' when the source finished a period period_done_in // should be '1' when the source finished a period
); );
@ -26,6 +27,7 @@ module CONTROLLER (
input rst_an; input rst_an;
//////////// OUTPUTS ////////// //////////// OUTPUTS //////////
output reg clear_states;
output reg ldq; output reg ldq;
output reg coeff_stb; output reg coeff_stb;
output reg signed [9:0] coeff_out; output reg signed [9:0] coeff_out;
@ -165,13 +167,14 @@ module CONTROLLER (
if (serve_pitch_data) if (serve_pitch_data)
begin begin
duration <= dur_tmp; duration <= dur_tmp;
amp_out <= {4'b0000, amp_tmp[15:4]}; //amp_out <= {4'b0000, amp_tmp[15:4]};
amp_out <= {amp_tmp[13:0],2'b00};
period_out <= period_tmp; period_out <= period_tmp;
end end
if (set_ldq == 1) if (set_ldq == 1)
ldq <= 1; ldq <= 1;
else if (reset_ldq == 1) else if (data_stb == 1)
ldq <= 0; ldq <= 0;
if ((period_done_in == 1) && (!serve_next_allo_data)) if ((period_done_in == 1) && (!serve_next_allo_data))
@ -243,25 +246,29 @@ module CONTROLLER (
dur_load <= 0; dur_load <= 0;
allo_load <= 0; allo_load <= 0;
load_cur_cmd <= 0; load_cur_cmd <= 0;
set_ldq <= 0; set_ldq <= 0;
reset_ldq <= 0; clear_states <= 0;
serve_pitch_data <= 0; serve_pitch_data <= 0;
dur_cnt_clear <= 0; dur_cnt_clear <= 0;
case (cur_state) case (cur_state)
S_IDLE: S_IDLE:
begin begin
set_ldq <= 1;
if (serve_next_allo_data == 1) if (serve_next_allo_data == 1)
begin begin
// we've run out of allophone data .. // we've run out of allophone data ..
end end
if (data_stb == 1) if (data_stb == 1)
begin begin
allo_load <= 1; allo_load <= 1;
//reset_ldq <= 1;
next_state <= S_JMPADDR1; next_state <= S_JMPADDR1;
end end
rom_addr_sel <= ROM_ADDR_ZERO; else
set_ldq <= 1;
rom_addr_sel <= ROM_ADDR_ZERO;
end end
S_JMPADDR1: S_JMPADDR1:
begin begin
@ -285,7 +292,6 @@ module CONTROLLER (
// perform jmp // perform jmp
rom_addr_sel <= ROM_ADDR_JMP; rom_addr_sel <= ROM_ADDR_JMP;
next_state <= S_CMDDECODE; next_state <= S_CMDDECODE;
reset_ldq <= 1;
end end
S_CMDDECODE: S_CMDDECODE:
begin begin
@ -334,7 +340,16 @@ module CONTROLLER (
begin begin
serve_pitch_data <= 1; serve_pitch_data <= 1;
dur_cnt_clear <= 1; dur_cnt_clear <= 1;
next_state <= (cur_cmd == 4'd2) ? S_LOADCOEF1 : S_CMDDECODE; if (cur_cmd == 4'd2)
begin
clear_states <= 1;
next_state <= S_LOADCOEF1;
end
else
begin
next_state <= S_CMDDECODE;
end
end end
end end
S_LOADCOEF1: S_LOADCOEF1:

View File

@ -11,6 +11,7 @@ module CONTROLLER_TB;
reg [5:0] data_in; reg [5:0] data_in;
reg data_stb, serve_next; reg data_stb, serve_next;
reg period_done; reg period_done;
wire clear_states;
wire ldq; wire ldq;
wire [9:0] coeff; wire [9:0] coeff;
@ -29,6 +30,7 @@ module CONTROLLER_TB;
.amp_out (amp), .amp_out (amp),
.coeff_out (coeff), .coeff_out (coeff),
.coeff_stb (coeff_load), .coeff_stb (coeff_load),
.clear_states (clear_states),
.period_done_in (period_done) .period_done_in (period_done)
); );

View File

@ -24,7 +24,7 @@ module XLAT (
output reg [9:0] c10_out; output reg [9:0] c10_out;
wire sign; wire sign;
assign sign = c8_in[7]; assign sign = ~c8_in[7];
always@(*) always@(*)
begin begin

View File

@ -20,7 +20,7 @@ module FILTER (
// coefficient loading interface // coefficient loading interface
coef_in, // 10 bit sign-magnitude coefficient coef_in, // 10 bit sign-magnitude coefficient
coef_load, // pulse '1' to load the coefficient into the internal register coef_load, // pulse '1' to load the coefficient into the internal register
clear_states, // set to '1' to reset internal filter states
// signal I/O and handshaking // signal I/O and handshaking
sig_in, // 16-bit (scaled) source input signal sig_in, // 16-bit (scaled) source input signal
sig_out, // 16-bit filter output signal sig_out, // 16-bit filter output signal
@ -39,6 +39,7 @@ module FILTER (
input signed [15:0] sig_in; input signed [15:0] sig_in;
input signed [9:0] coef_in; input signed [9:0] coef_in;
input start, coef_load; input start, coef_load;
input clear_states; // zero all states
//////////// FILTER OUTPUTS ////////// //////////// FILTER OUTPUTS //////////
output wire signed [15:0] sig_out; output wire signed [15:0] sig_out;
@ -56,7 +57,7 @@ module FILTER (
reg do_accu; // if 1, the accumulator is updated reg do_accu; // if 1, the accumulator is updated
reg double_mode; // if 1, the input to the accumulator is x2 reg double_mode; // if 1, the input to the accumulator is x2
reg update_states; // shift the state registers reg update_states; // shift the state registers
reg clear_states; // zero all states
reg update_coeffs; // shift the coefficient registers reg update_coeffs; // shift the coefficient registers
reg [3:0] cur_state; // current FSM state reg [3:0] cur_state; // current FSM state
reg [3:0] next_state; // next FSM state reg [3:0] next_state; // next FSM state

View File

@ -6,7 +6,7 @@
// //
module FILTER_TB; module FILTER_TB;
reg clk, rst_an, start, coef_load, check_finish; reg clk, rst_an, start, coef_load, check_finish, clear_states;
reg signed [15:0] sig_in; reg signed [15:0] sig_in;
reg signed [9:0] coef_in; reg signed [9:0] coef_in;
reg [3:0] reg_sel; reg [3:0] reg_sel;
@ -22,6 +22,7 @@ module FILTER_TB;
.rst_an (rst_an), .rst_an (rst_an),
.coef_in (coef_in), .coef_in (coef_in),
.coef_load (coef_load), .coef_load (coef_load),
.clear_states (clear_states),
.sig_in (sig_in), .sig_in (sig_in),
.sig_out (sig_out), .sig_out (sig_out),
.start (start), .start (start),
@ -41,6 +42,7 @@ module FILTER_TB;
coef_in = 0; coef_in = 0;
coef_load = 0; coef_load = 0;
start = 0; start = 0;
clear_states = 0;
check_finish = 0; check_finish = 0;
#10 #10
@ -52,29 +54,29 @@ module FILTER_TB;
#10 #10
coef_load = 1; coef_load = 1;
// section 1 // section 1
coef_in = 10'h3C9; coef_in = 10'h1C9;
#10 #10
coef_in = 10'h1E4; coef_in = 10'h3E4;
#10 #10
// section 2 // section 2
coef_in = 10'h2B8; coef_in = 10'h0B8;
#10 #10
coef_in = 10'h1CF; coef_in = 10'h3CF;
#10 #10
// section 3 // section 3
coef_in = 10'h238; coef_in = 10'h038;
#10 #10
coef_in = 10'h080; coef_in = 10'h280;
#10 #10
// section 4 // section 4
coef_in = 10'h195; coef_in = 10'h395;
#10 #10
coef_in = 10'h1BF; coef_in = 10'h3BF;
#10 #10
// section 5 // section 5
coef_in = 10'h135; coef_in = 10'h335;
#10 #10
coef_in = 10'h1BF; coef_in = 10'h3BF;
#10 #10
// section 6 // section 6
coef_in = 10'h000; coef_in = 10'h000;
@ -118,7 +120,7 @@ module FILTER_TB;
#10 #10
coef_load = 0; coef_load = 0;
start = 1; start = 1;
#10000; #20000;
check_finish = 1; check_finish = 1;
end end

View File

@ -7,12 +7,14 @@
// //
module SPEECH256_TOP ( module SPEECH256_TOP (
clk, // global Speech256 clock clk, // global Speech256 clock (256*10kHz)
rst_an, rst_an,
ldq, // load request, is high when new allophone can be loaded ldq, // load request, is high when new allophone can be loaded
data_in, // allophone input data_in, // allophone input
data_stb, // allophone strobe input data_stb, // allophone strobe input
dac_out, // 1-bit PWM DAC output pwm_out, // 1-bit PWM DAC output
sample_out,
sample_stb
); );
//////////// CLOCK ////////// //////////// CLOCK //////////
@ -22,8 +24,10 @@ module SPEECH256_TOP (
input rst_an; input rst_an;
//////////// OUTPUTS ////////// //////////// OUTPUTS //////////
output dac_out; output pwm_out;
output ldq; output ldq;
output signed [15:0] sample_out;
output sample_stb;
//////////// INPUTS ////////// //////////// INPUTS //////////
input [5:0] data_in; input [5:0] data_in;
@ -35,6 +39,7 @@ module SPEECH256_TOP (
wire signed [15:0] sig_source; wire signed [15:0] sig_source;
wire signed [15:0] sig_filter; wire signed [15:0] sig_filter;
wire period_done; wire period_done;
wire clear_states;
wire [7:0] period; wire [7:0] period;
wire [7:0] dur; wire [7:0] dur;
@ -60,6 +65,7 @@ module SPEECH256_TOP (
.rst_an (rst_an), .rst_an (rst_an),
.coef_in (coef_bus), .coef_in (coef_bus),
.coef_load (coef_load), .coef_load (coef_load),
.clear_states (clear_states),
.sig_in (sig_source), .sig_in (sig_source),
.sig_out (sig_filter), .sig_out (sig_filter),
.start (pwmdac_ack), .start (pwmdac_ack),
@ -71,7 +77,7 @@ module SPEECH256_TOP (
.rst_an (rst_an), .rst_an (rst_an),
.din (sig_filter[15:8]), .din (sig_filter[15:8]),
.din_ack (pwmdac_ack), .din_ack (pwmdac_ack),
.dacout (dac_out) .dacout (pwm_out)
); );
CONTROLLER u_controller ( CONTROLLER u_controller (
@ -84,9 +90,13 @@ module SPEECH256_TOP (
.amp_out (amp), .amp_out (amp),
.coeff_out (coef_bus), .coeff_out (coef_bus),
.coeff_stb (coef_load), .coeff_stb (coef_load),
.clear_states (clear_states),
.period_done_in (period_done) .period_done_in (period_done)
); );
assign sample_out = sig_filter[15:0];
assign sample_stb = src_strobe;
always @(posedge clk, negedge rst_an) always @(posedge clk, negedge rst_an)
begin begin
if (rst_an == 0) if (rst_an == 0)

View File

@ -9,7 +9,12 @@ module SPEECH256_TOP_TB;
reg clk, rst_an; reg clk, rst_an;
reg [5:0] data_in; reg [5:0] data_in;
reg data_stb; reg data_stb;
wire ldq,dac_out; wire sample_stb;
wire signed [15:0] sample_out;
wire ldq,pwm_out;
reg [7:0] allophones[0:10];
reg [3:0] allo_idx;
SPEECH256_TOP u_speech256_top ( SPEECH256_TOP u_speech256_top (
.clk (clk), .clk (clk),
@ -17,34 +22,65 @@ module SPEECH256_TOP_TB;
.ldq (ldq), .ldq (ldq),
.data_in (data_in), .data_in (data_in),
.data_stb (data_stb), .data_stb (data_stb),
.dac_out (dac_out) .pwm_out (pwm_out),
.sample_out (sample_out),
.sample_stb (sample_stb)
); );
integer fd; // file descriptor integer fd; // file descriptor
initial initial
begin begin
// hello, world
allophones[0] = 6'h1B;
allophones[1] = 6'h07;
allophones[2] = 6'h2D;
allophones[3] = 6'h35;
allophones[4] = 6'h03;
allophones[5] = 6'h2E;
allophones[6] = 6'h1E;
allophones[7] = 6'h33;
allophones[8] = 6'h2D;
allophones[9] = 6'h15;
allophones[10] = 6'h03;
allophones[11] = 6'h00;
fd = $fopen("dacout.sw","wb"); fd = $fopen("dacout.sw","wb");
$dumpfile ("speech256_top.vcd"); $dumpfile ("speech256_top.vcd");
$dumpvars; $dumpvars;
clk = 0; clk = 0;
rst_an = 0; rst_an = 0;
data_stb = 0; allo_idx = 0;
#5 #5
rst_an = 1; rst_an <= 1;
#5 //#5
data_in = 7; //#9000000
data_stb = 1;
#5
data_stb = 0;
#300000
//$fclose(fd); //$fclose(fd);
$finish; //$finish;
end end
reg last_sample_stb;
always @(posedge clk) always @(posedge clk)
begin begin
$fwrite(fd,"%u", {31'd0,dac_out}); // check for new output sample
if ((sample_stb == 1) && (last_sample_stb != sample_stb))
begin
$fwrite(fd,"%u", $signed( {sample_out, 16'h0000} ));
end
last_sample_stb <= sample_stb;
// check for next allophone
if ((ldq == 1) && (data_stb == 0))
begin
data_stb <= 1;
data_in <= allophones[allo_idx];
$display("Allophone %d", allo_idx);
allo_idx <= allo_idx + 1;
if (allo_idx == 11)
$finish;
end
else
data_stb <= 0;
end end
always always