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
|
||||
coeff_out, // 8-bit coefficient data out
|
||||
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
|
||||
);
|
||||
|
||||
@ -26,6 +27,7 @@ module CONTROLLER (
|
||||
input rst_an;
|
||||
|
||||
//////////// OUTPUTS //////////
|
||||
output reg clear_states;
|
||||
output reg ldq;
|
||||
output reg coeff_stb;
|
||||
output reg signed [9:0] coeff_out;
|
||||
@ -165,13 +167,14 @@ module CONTROLLER (
|
||||
if (serve_pitch_data)
|
||||
begin
|
||||
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;
|
||||
end
|
||||
|
||||
if (set_ldq == 1)
|
||||
ldq <= 1;
|
||||
else if (reset_ldq == 1)
|
||||
else if (data_stb == 1)
|
||||
ldq <= 0;
|
||||
|
||||
if ((period_done_in == 1) && (!serve_next_allo_data))
|
||||
@ -244,14 +247,14 @@ module CONTROLLER (
|
||||
allo_load <= 0;
|
||||
load_cur_cmd <= 0;
|
||||
set_ldq <= 0;
|
||||
reset_ldq <= 0;
|
||||
clear_states <= 0;
|
||||
|
||||
serve_pitch_data <= 0;
|
||||
dur_cnt_clear <= 0;
|
||||
|
||||
case (cur_state)
|
||||
S_IDLE:
|
||||
begin
|
||||
set_ldq <= 1;
|
||||
if (serve_next_allo_data == 1)
|
||||
begin
|
||||
// we've run out of allophone data ..
|
||||
@ -259,8 +262,12 @@ module CONTROLLER (
|
||||
if (data_stb == 1)
|
||||
begin
|
||||
allo_load <= 1;
|
||||
//reset_ldq <= 1;
|
||||
next_state <= S_JMPADDR1;
|
||||
end
|
||||
else
|
||||
set_ldq <= 1;
|
||||
|
||||
rom_addr_sel <= ROM_ADDR_ZERO;
|
||||
end
|
||||
S_JMPADDR1:
|
||||
@ -285,7 +292,6 @@ module CONTROLLER (
|
||||
// perform jmp
|
||||
rom_addr_sel <= ROM_ADDR_JMP;
|
||||
next_state <= S_CMDDECODE;
|
||||
reset_ldq <= 1;
|
||||
end
|
||||
S_CMDDECODE:
|
||||
begin
|
||||
@ -334,7 +340,16 @@ module CONTROLLER (
|
||||
begin
|
||||
serve_pitch_data <= 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
|
||||
S_LOADCOEF1:
|
||||
|
@ -11,6 +11,7 @@ module CONTROLLER_TB;
|
||||
reg [5:0] data_in;
|
||||
reg data_stb, serve_next;
|
||||
reg period_done;
|
||||
wire clear_states;
|
||||
|
||||
wire ldq;
|
||||
wire [9:0] coeff;
|
||||
@ -29,6 +30,7 @@ module CONTROLLER_TB;
|
||||
.amp_out (amp),
|
||||
.coeff_out (coeff),
|
||||
.coeff_stb (coeff_load),
|
||||
.clear_states (clear_states),
|
||||
.period_done_in (period_done)
|
||||
);
|
||||
|
||||
|
@ -24,7 +24,7 @@ module XLAT (
|
||||
output reg [9:0] c10_out;
|
||||
wire sign;
|
||||
|
||||
assign sign = c8_in[7];
|
||||
assign sign = ~c8_in[7];
|
||||
|
||||
always@(*)
|
||||
begin
|
||||
|
@ -20,7 +20,7 @@ module FILTER (
|
||||
// coefficient loading interface
|
||||
coef_in, // 10 bit sign-magnitude coefficient
|
||||
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
|
||||
sig_in, // 16-bit (scaled) source input signal
|
||||
sig_out, // 16-bit filter output signal
|
||||
@ -39,6 +39,7 @@ module FILTER (
|
||||
input signed [15:0] sig_in;
|
||||
input signed [9:0] coef_in;
|
||||
input start, coef_load;
|
||||
input clear_states; // zero all states
|
||||
|
||||
//////////// FILTER OUTPUTS //////////
|
||||
output wire signed [15:0] sig_out;
|
||||
@ -56,7 +57,7 @@ module FILTER (
|
||||
reg do_accu; // if 1, the accumulator is updated
|
||||
reg double_mode; // if 1, the input to the accumulator is x2
|
||||
reg update_states; // shift the state registers
|
||||
reg clear_states; // zero all states
|
||||
|
||||
reg update_coeffs; // shift the coefficient registers
|
||||
reg [3:0] cur_state; // current FSM state
|
||||
reg [3:0] next_state; // next FSM state
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
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 [9:0] coef_in;
|
||||
reg [3:0] reg_sel;
|
||||
@ -22,6 +22,7 @@ module FILTER_TB;
|
||||
.rst_an (rst_an),
|
||||
.coef_in (coef_in),
|
||||
.coef_load (coef_load),
|
||||
.clear_states (clear_states),
|
||||
.sig_in (sig_in),
|
||||
.sig_out (sig_out),
|
||||
.start (start),
|
||||
@ -41,6 +42,7 @@ module FILTER_TB;
|
||||
coef_in = 0;
|
||||
coef_load = 0;
|
||||
start = 0;
|
||||
clear_states = 0;
|
||||
check_finish = 0;
|
||||
|
||||
#10
|
||||
@ -52,29 +54,29 @@ module FILTER_TB;
|
||||
#10
|
||||
coef_load = 1;
|
||||
// section 1
|
||||
coef_in = 10'h3C9;
|
||||
coef_in = 10'h1C9;
|
||||
#10
|
||||
coef_in = 10'h1E4;
|
||||
coef_in = 10'h3E4;
|
||||
#10
|
||||
// section 2
|
||||
coef_in = 10'h2B8;
|
||||
coef_in = 10'h0B8;
|
||||
#10
|
||||
coef_in = 10'h1CF;
|
||||
coef_in = 10'h3CF;
|
||||
#10
|
||||
// section 3
|
||||
coef_in = 10'h238;
|
||||
coef_in = 10'h038;
|
||||
#10
|
||||
coef_in = 10'h080;
|
||||
coef_in = 10'h280;
|
||||
#10
|
||||
// section 4
|
||||
coef_in = 10'h195;
|
||||
coef_in = 10'h395;
|
||||
#10
|
||||
coef_in = 10'h1BF;
|
||||
coef_in = 10'h3BF;
|
||||
#10
|
||||
// section 5
|
||||
coef_in = 10'h135;
|
||||
coef_in = 10'h335;
|
||||
#10
|
||||
coef_in = 10'h1BF;
|
||||
coef_in = 10'h3BF;
|
||||
#10
|
||||
// section 6
|
||||
coef_in = 10'h000;
|
||||
@ -118,7 +120,7 @@ module FILTER_TB;
|
||||
#10
|
||||
coef_load = 0;
|
||||
start = 1;
|
||||
#10000;
|
||||
#20000;
|
||||
check_finish = 1;
|
||||
end
|
||||
|
||||
|
@ -7,12 +7,14 @@
|
||||
//
|
||||
|
||||
module SPEECH256_TOP (
|
||||
clk, // global Speech256 clock
|
||||
clk, // global Speech256 clock (256*10kHz)
|
||||
rst_an,
|
||||
ldq, // load request, is high when new allophone can be loaded
|
||||
data_in, // allophone 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 //////////
|
||||
@ -22,8 +24,10 @@ module SPEECH256_TOP (
|
||||
input rst_an;
|
||||
|
||||
//////////// OUTPUTS //////////
|
||||
output dac_out;
|
||||
output pwm_out;
|
||||
output ldq;
|
||||
output signed [15:0] sample_out;
|
||||
output sample_stb;
|
||||
|
||||
//////////// INPUTS //////////
|
||||
input [5:0] data_in;
|
||||
@ -35,6 +39,7 @@ module SPEECH256_TOP (
|
||||
wire signed [15:0] sig_source;
|
||||
wire signed [15:0] sig_filter;
|
||||
wire period_done;
|
||||
wire clear_states;
|
||||
|
||||
wire [7:0] period;
|
||||
wire [7:0] dur;
|
||||
@ -60,6 +65,7 @@ module SPEECH256_TOP (
|
||||
.rst_an (rst_an),
|
||||
.coef_in (coef_bus),
|
||||
.coef_load (coef_load),
|
||||
.clear_states (clear_states),
|
||||
.sig_in (sig_source),
|
||||
.sig_out (sig_filter),
|
||||
.start (pwmdac_ack),
|
||||
@ -71,7 +77,7 @@ module SPEECH256_TOP (
|
||||
.rst_an (rst_an),
|
||||
.din (sig_filter[15:8]),
|
||||
.din_ack (pwmdac_ack),
|
||||
.dacout (dac_out)
|
||||
.dacout (pwm_out)
|
||||
);
|
||||
|
||||
CONTROLLER u_controller (
|
||||
@ -84,9 +90,13 @@ module SPEECH256_TOP (
|
||||
.amp_out (amp),
|
||||
.coeff_out (coef_bus),
|
||||
.coeff_stb (coef_load),
|
||||
.clear_states (clear_states),
|
||||
.period_done_in (period_done)
|
||||
);
|
||||
|
||||
assign sample_out = sig_filter[15:0];
|
||||
assign sample_stb = src_strobe;
|
||||
|
||||
always @(posedge clk, negedge rst_an)
|
||||
begin
|
||||
if (rst_an == 0)
|
||||
|
@ -9,7 +9,12 @@ module SPEECH256_TOP_TB;
|
||||
reg clk, rst_an;
|
||||
reg [5:0] data_in;
|
||||
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 (
|
||||
.clk (clk),
|
||||
@ -17,34 +22,65 @@ module SPEECH256_TOP_TB;
|
||||
.ldq (ldq),
|
||||
.data_in (data_in),
|
||||
.data_stb (data_stb),
|
||||
.dac_out (dac_out)
|
||||
.pwm_out (pwm_out),
|
||||
.sample_out (sample_out),
|
||||
.sample_stb (sample_stb)
|
||||
);
|
||||
|
||||
integer fd; // file descriptor
|
||||
|
||||
initial
|
||||
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");
|
||||
$dumpfile ("speech256_top.vcd");
|
||||
$dumpvars;
|
||||
clk = 0;
|
||||
rst_an = 0;
|
||||
data_stb = 0;
|
||||
allo_idx = 0;
|
||||
#5
|
||||
rst_an = 1;
|
||||
#5
|
||||
data_in = 7;
|
||||
data_stb = 1;
|
||||
#5
|
||||
data_stb = 0;
|
||||
#300000
|
||||
rst_an <= 1;
|
||||
//#5
|
||||
//#9000000
|
||||
//$fclose(fd);
|
||||
$finish;
|
||||
//$finish;
|
||||
end
|
||||
|
||||
reg last_sample_stb;
|
||||
always @(posedge clk)
|
||||
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
|
||||
|
||||
always
|
||||
|
Loading…
x
Reference in New Issue
Block a user