mirror of
https://github.com/trcwm/Speech256.git
synced 2025-06-07 16:48:32 +02:00
First working simulation of 'hello, world' :)
This commit is contained in:
parent
31163effd9
commit
10d9735e11
@ -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:
|
||||||
|
@ -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)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user