Commit 800b391b authored by Tannin Rachel's avatar Tannin Rachel
Browse files

所有代码,但song_reader_ctrl.v报错

parent 7f435f6f
`timescale 1ns / 1ps
module counter_n_tb;
reg clk;
reg en;
reg r;
wire co;
wire [2:0] q;
counter #(.n(5),.counter_bits(3)) uut (.clk(clk), .r(r), .en(en), .q(q), .co(co));
//clk
always #50 clk=~clk;
initial
begin
clk = 0;r=0;en = 0;
#(51) r=1;
#(100)r=0;en=1;
#(800)
repeat (10) begin
#(100*3) en=1;
#100 en=0; end
#100 $stop;
end
endmodule
module music_player(
clk,
reset,
play_pause,
next,
NewFrame,
sample,
play,
song
);
parameter sim = 0;
input clk, reset, play_pause, next, NewFrame;
output [15:0] sample;
output play;
output [1:0] song;
wire ready, beat, reset_play, song_done, new_note, note_done;
wire [5:0] note, duration;
wire sample_ready;
// 同步化电路
synch i1(
.clk(clk),
.in(NewFrame),
.out(ready)
);
// 节拍基准产生器
counter #(.n(sim?64:1000), .counter_bits(sim?6:10)) i2(
.clk(clk),
.r(0),
.en(ready),
.q(),
.co(beat)
);
// 主控制器
mcu c1(
.clk(clk),
.reset(reset),
.play_pause(play_pause),
.next(next),
.play(play),
.song(song),
.reset_play(reset_play),
.song_done(song_done)
);
// 乐曲读取
song_reader c2(
.clk(clk),
.reset(reset_play),
.play(play),
.song(song),
.song_done(song_done),
.note(note),
.duration(duration),
.new_note(new_note),
.note_done(note_done)
);
// 音符播放
note_player c3(
.clk(clk),
.reset(reset_play),
.play_enable(play),
.note_to_load(note),
.duration_to_load(duration),
.note_done(note_done),
.load_new_note(new_note),
.beat(beat),
.sampling_pulse(ready),
.sample(sample),
.sample_ready(sample_ready)
);
endmodule // music_player
\ No newline at end of file
module note_player(
clk, // 系统时钟信号,外接sys_clk
reset, // 复位信号,高电平有效,外接mcu模块的reset_play
play_enable, // 来自mcu模块的play信号,高电平表示播放
note_to_load, // 来自song_reader模块的音符标记note,表示需播放的音符
duration_to_load, // 来自song_reader模块的音符时长duration,表示需播放音符的音长
note_done, // 给song_reader模块的应答信号,一个时钟周期宽度的高电平脉冲,表示音符播放完毕
load_new_note, // 来自song_raeder模块的new_note信号,一个时钟周期宽度的高电平脉冲,表示新的音符需播放
beat, // 定时基准信号,频率为48kHz脉冲,一个时钟周期宽度的高电平脉冲
sampling_pulse, // 来自同步化电路模块的ready信号,频率48kHz,表示索取新的样品
sample, // 正弦样品输出
sample_ready // 下一个正弦信号
);
input clk, reset, play_enable, load_new_note, beat, sampling_pulse;
input [5:0] note_to_load, duration_to_load;
output note_done, sample_ready;
output [15:0] sample;
wire [5:0] q; // FreqROM的地址输入
wire [19:0] dout;
wire timer_clear, timer_done; // 计时清空和计时完成
// 控制器
note_player_ctrl np(
.clk(clk),
.reset(reset),
.play_enable(play_enable),
.load_new_note(load_new_note),
.load(load), // D触发器的使能输入
.timer_clear(timer_clear), // 音符节拍定时器计时清空
.timer_done(timer_done), // 音符节拍定时器计时完成
.note_done(note_done)
);
// D触发器
dffre#(.n(6)) df(
.d(note_to_load),
.en(load),
.r(~play_enable || reset), // 清零信号
.clk(clk),
.q(q) // FreqROM地址输入
);
// FreqROM
frequency_rom fr(
.clk(clk),
.dout(dout), // DDS模块k的后20位
.addr(q)
);
// DDS
dds ds(
.clk(clk),
.reset(~play_enable || reset),
.k({2'b00, dout}),
.sampling_pulse(sampling_pulse),
.new_sample_ready(sample_ready),
.sample(sample)
);
// 计时器
timer tm(
.clk(clk),
.beat(beat), // 使能端
.q(duration_to_load), // 计时长度
.din(timer_clear),
.dout(timer_done)
);
endmodule // note_player
\ No newline at end of file
module note_player_ctrl(
clk,
reset,
play_enable,
load_new_note,
load,
timer_clear,
timer_done,
note_done
);
input clk, reset, play_enable, load_new_note, timer_done;
output note_done, timer_clear, load;
reg timer_clear, load, note_done;
reg [1:0] state, nextstate;
parameter RESET = 0, WAIT = 1, DONE = 2, LOAD = 3; //状态编码
always @(posedge clk) begin
if(reset) state = RESET;
else state = nextstate;
end
always @(*) begin
timer_clear = 0; load = 0; note_done = 0; // 初始值
case (state)
RESET: begin timer_clear = 1; nextstate = WAIT; end
WAIT: begin
if(play_enable) begin
if(timer_done) nextstate = DONE;
else begin
if(load_new_note) nextstate = LOAD;
else nextstate = WAIT;
end
end
else nextstate = RESET;
end
DONE: begin timer_clear = 1; note_done = 1; nextstate = WAIT; end
LOAD: begin timer_clear = 1; load = 1; nextstate = WAIT; end
endcase
end
endmodule // note_player_ctrl
\ No newline at end of file
...@@ -14,7 +14,7 @@ end ...@@ -14,7 +14,7 @@ end
// 下一状态和输出电路 // 下一状态和输出电路
always @(posedge clk) begin always @(posedge clk) begin
note_done = 0; play = 0; new_note = 0; new_note = 0;
case(state) case(state)
RESET: begin RESET: begin
if(play) nextstate = NEW_NOTE; if(play) nextstate = NEW_NOTE;
...@@ -25,7 +25,6 @@ always @(posedge clk) begin ...@@ -25,7 +25,6 @@ always @(posedge clk) begin
nextstate = WAIT; nextstate = WAIT;
end end
WAIT: begin WAIT: begin
new_note = 0;
if(play) begin if(play) begin
if(note_done) nextstate = NEXT_NOTE; if(note_done) nextstate = NEXT_NOTE;
else nextstate = WAIT; else nextstate = WAIT;
...@@ -33,7 +32,6 @@ always @(posedge clk) begin ...@@ -33,7 +32,6 @@ always @(posedge clk) begin
else nextstate = RESET; else nextstate = RESET;
end end
NEXT_NOTE: begin NEXT_NOTE: begin
new_note = 0;
nextstate = NEW_NOTE; nextstate = NEW_NOTE;
end end
default: nextstate = RESET; default: nextstate = RESET;
......
module synch(clk, in, out);
input clk, in;
output out;
reg q1, q2;
always @(posedge clk) begin
q1 <= in;
q2 <= q1;
end
assign out = q1 && (~q2);
endmodule // synch
\ No newline at end of file
`timescale 1ns / 1ps
module synch_tb;
parameter delay = 10;
reg clk, in;
wire out;
synch i1(
.clk(clk),
.in(in),
.out(out)
);
initial
begin
clk = 0;
in = 0;
#(delay+1) in=0;
#(delay) in = 1;
#(delay) in = 0;
repeat (20000)
begin
#(delay*5) in = 1;
#(delay) in = 0;
end
#(delay*10) $stop;
end
always #(delay/2) clk=~clk;
endmodule // synch_tb
\ No newline at end of file
module timer(
clk,
beat,
q, // 计时长度
din,
dout); // 计时结束输出
input clk, beat, din;
input [5:0] q;
output dout;
reg [5:0] cnt = 0;
assign dout = (cnt==q-1); // 计时结束
always @(posedge clk) begin
if(din) cnt = 0; // reset信号
else begin if(beat) cnt = cnt+1; // beat高电平则计时+1
else cnt = cnt; end
end
endmodule // timer
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment