3
678900123451024231212102412163218876543211324575678912342212211411343658723910012111214141316152181712012121922212423181FPGA电路原理图 主板PCB图 21721212163115414513211917151311697531122220181614121078642118431092152361121233221041102211112201122
附录B
FPGA程序
/*============================================ File: analog.v
Function: 以8.3Kbps采样vol_in上的语音信号,并通过ADC_data端口输出 =============================================*/
module analog( clk_48m, reset, vol_in, vref, ADC_trig, ADC_data );
input clk_48m; // 系统输入时钟48M input reset; // 异步复位信号
input vol_in; // 模拟语音信号输入 output vref; // 参考电压输出
output ADC_trig; // 在此信号的上升沿,输出数据 output [7:0] ADC_data; // 采样后的8位并行数据
reg irq; // 在此信号的上升沿输出数据 reg [3:0] samp_div; // 数据抽样步长寄存器 reg [7:0] ADC_out; // ADC抽样输出 reg [7:0] ADC_temp; // ADC输出寄存 reg edge_detect1,edge_detect2; // 边沿检测寄存器
wire [11:0] ADC_result; // ADC输出
wire [8:0] init_data; // ADC初始化数据总线 wire [8:0] init_addr; // ADC初始化地址总线 wire [4:0] chanel; // ADC的采样通道号
wire assc_done; // ADC在此信号上升沿输出有效采样数据 wire edge_found; // 标识assc_done的上升沿 assign ADC_data = ADC_out; assign ADC_trig = irq;
//***************************************************************************** // 模块名称:边沿检测
// 功能描述:检测assc_done信号的上升沿
//***************************************************************************** assign edge_found=edge_detect1 && (~edge_detect2); always @(posedge clk_48m or posedge reset) begin
if(reset) begin
edge_detect1<=0; edge_detect2<=0; end else begin
edge_detect1<=assc_done; // 一级同步 edge_detect2<=edge_detect1; // 二级同步
end end
//***************************************************************************** // 模块名称:ADC抽样输出
// 功能描述:以10为步长抽样输出ADC的采样结果
//***************************************************************************** always @(posedge clk_48m or posedge reset) begin
if(reset) begin
samp_div <= 0; irq <= 0;
ADC_out <= 0; ADC_temp <= 0; end
else if(edge_found) begin
if(samp_div==9) // 抽样步长为10 begin
samp_div <= 0;
irq <= 1; // irq标识数据进行了更新 ADC_out <= ADC_temp; // 对采样结果抽样 end else begin
samp_div <= samp_div+1; irq <= 0;
if(ADC_result[11:4]!=0)
ADC_temp <= ADC_result[11:4]; // 经验表明ADC偶尔会将信号误采为0,
发生此情况时则舍弃数据
end end end
//***************************************************************************** // 模块名称:analog_flash_0 // 功能描述:初始化ADC
//***************************************************************************** analog_flash analog_flash_0 (
.INIT_CLK(acm_clk), .SYS_RESET(~reset), .INIT_POWER_UP(1'b1), .INIT_DONE(init_done), .INIT_DATA(init_data), .INIT_ADDR(init_addr),
.INIT_ACM_WEN(init_acm_wen), .INIT_ASSC_WEN(init_assc_wen), .INIT_EV_WEN(init_ev_wen), .INIT_TR_WEN(init_tr_wen) );
//***************************************************************************** // 模块名称:analog_fusion_0 // 功能描述:AD采样
//***************************************************************************** analog_fusion analog_fusion_0
(
.SYS_CLK(clk_48m), .SYS_RESET(~reset), .VAREF(vref),
.DATAVALID(datavalid), .in_vol(vol_in),
.ASSC_DONE(assc_done), .ASSC_WAIT(), .ASSC_CHSAT(), .ASSC_CHLATD(), .INIT_ADDR(init_addr), .INIT_DATA(init_data),
.INIT_ACM_WEN(init_acm_wen), .INIT_ASSC_WEN(init_assc_wen), .INIT_EV_WEN(init_ev_wen), .INIT_TR_WEN(init_tr_wen), .INIT_DONE(init_done),
.ADC_RESULT(ADC_result), .ADC_CHNUMBER(chanel), .ACMCLK(acm_clk) );
//***************************************************************************** // 模块名称:pll_fusion_0
// 功能描述:给AD采样模块提供2M的配置时钟
//***************************************************************************** pll_fusion pll_fusion_0 (
.POWERDOWN(1'b1), .CLKA(clk_48m), .LOCK(), .GLA(),
.GLB(acm_clk), .OADIVRST(1'b0) );
endmodule
/*============================================ File: top.v
Function: 电话录音系统顶层模块,用于将各个子模块连接起来 =============================================*
module top(
reset /* synthesis syn_noclockbuf = 1 */, clk_48m, vol_in, hold, q, std,
fsk_in, vref, pub,
phonesnd, vr_ok, txd, ctrl );
input reset; // 48MHz时钟信号 input clk_48m; // 异步复位信号 input vol_in; // 语音输入 input hold; // 摘机信号
input [3:0] q; // MT8870解码输出
input std; // MT8870数据有效标识 input fsk_in; // fsk信号输入 output vref; // 参考电压 input pub; // VR唤醒输入 input phonesnd; // 忙音输入
output vr_ok; // VR初始化完毕标识 output txd; // UART发送线
output ctrl; // 外部语音提取电路选通控制
wire [7:0] ADC_data; // ADC采样模块数据输出 wire ADC_trig; // ADC采样模块发送触发 wire [3:0] dtmf_data; // DTMF解码模块数据输出 wire dtmf_trig; // DTMF解码模块发送触发 wire [7:0] fsk_data; // FSK解码模块数据输出 wire fsk_trig; // FSK解码模块发送触发 wire [7:0] txd_data; // UART发送模块数据输出 wire [7:0] Dataout; // UART接收模块数据输出 wire [2:0] CS; // 通道选择控制信号
wire decode_out; // FSK解码模块bit流输出 wire ring_out; // 振铃信号
wire fsk_over; // FSK通道结束信号 wire dtmf_over; // DTMF通道结束信号 wire adc_over; // ADC通道结束信号 wire busy_snd; // 忙音信号
//***************************************************************************** // 模块名称:analog_0 // 功能描述:ADC采样
//***************************************************************************** analog analog_0 (
.reset(reset), // 高电平有效的异步复位信号 .clk_48m(clk_48m), // 48M时钟 .vol_in(vol_in), // 语音输入
.vref(vref), // 参考电压输出 .ADC_data(ADC_data), // AD采样输出 .ADC_trig(ADC_trig) // 发送触发 );
//***************************************************************************** // 模块名称:uart_txd_0 // 功能描述:UART发送
//***************************************************************************** uart_txd_0 ( .clk_48m(clk_48m), // 48MHz时钟 .reset(reset), // 复位,高有效 .txd_start(txd_trig), // 发送开始信号,上升沿有效 .txd_data(txd_data) , // 将要发送的的数据,字节
uart_txd