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
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))
@ -243,25 +246,29 @@ module CONTROLLER (
dur_load <= 0;
allo_load <= 0;
load_cur_cmd <= 0;
set_ldq <= 0;
reset_ldq <= 0;
set_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 ..
// we've run out of allophone data ..
end
if (data_stb == 1)
begin
allo_load <= 1;
//reset_ldq <= 1;
next_state <= S_JMPADDR1;
end
rom_addr_sel <= ROM_ADDR_ZERO;
end
else
set_ldq <= 1;
rom_addr_sel <= ROM_ADDR_ZERO;
end
S_JMPADDR1:
begin
@ -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:

View File

@ -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)
);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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});
begin
// 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