博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于音频总线IIS的学习---Verilog

Posted on 2018-06-08 14:45  沉默改良者  阅读(1895)  评论(0编辑  收藏  举报

关于音频总线IIS的学习---Verilog

主要思想: 在分析寄存器的值变化的时候,将时钟的边沿分两边来看,边沿之前,边沿之后,在always 块语句里面用来分析判断的寄存器的值,都应该用边沿变化之前的值,边沿之后, always块做操作的寄存器的值才发生变化。

记住,一定是寄存器量(reg定义的),像audio_sck 这种外部输入的异步信号要判断上升沿状态下的即时值。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:  chensimin
// 
// Create Date: 2018/06/08 13:33:40
// Design Name: 
// Module Name: iis_s2p
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module iis_s2p(

    input    wire        reset,
    input    wire        clk,    // 12.288
    input    wire        audio_sck,
    input    wire        audio_ws

    );



//-----------------------------------------------
//将外部输入的sck,ws 信号通过时钟clk进行同步采集进来
    reg audio_sck_d = 0;
    reg audio_ws_d = 0;
    always @(posedge clk or posedge reset)
    begin
        if(reset)
        begin
            audio_sck_d <= 1'b0;
            audio_ws_d <= 1'b0;
        end

        else 
        begin
            audio_sck_d <= audio_sck;
            audio_ws_d <= audio_ws;
        end
    end


//-----------------------------------------------
//监测audio_sck 信号的下降沿
//疑问:为什么不采用组合逻辑的方式
//assign sck_neg  =   audio_sck_d &   ~audio_sck ;
    reg sck_neg = 0;
    always @(posedge clk or posedge reset)
    begin
        if(reset)
            sck_neg <= 1'b0;

        else if (audio_sck_d & audio_sck)
            sck_neg <= 1'b1;

        else
            sck_neg <= 1'b0;
    end


endmodule

/*

add_force {/iis_s2p/clk} -radix hex {1 0ns} {0 5000ps} -repeat_every 10000ps
add_force {/iis_s2p/audio_sck} -radix hex {1 0ns} {0 20000ps} -repeat_every 40000ps
add_force {/iis_s2p/reset} -radix hex {1 0ns} {0 20ns}

*/

仿真结果:

分析:

1.从仿真结果可以看出为什么不能用通常的assign语句来检测sck的下降沿信号,因为sck_neg为外部输入信号,通过时钟采集存入sck_d寄存器中,两个信号波形完全一样,根本就不会有sck_neg置高的时候。

2.信号过了主时钟,存入寄存器,寄存器值的变化分析方法:

以主时钟的上升沿为边界,分为 :上升沿到来之前, 上升沿,上升沿之后,数据是在上升沿之后进行更新。

对于如下模块:

//-----------------------------------------------
//结合波形图来看,clk上升沿到来之前,寄存器中audio_sck_d的数据为0,clk上升沿时,将audio_sck_d里面的数据进行更新,clk上升沿之后,audio_sck_d里面的数据发生变化
//将外部输入的sck,ws 信号通过时钟clk进行同步采集进来 reg audio_sck_d = 0; reg audio_ws_d = 0; always @(posedge clk or posedge reset) begin if(reset) begin audio_sck_d <= 1'b0; audio_ws_d <= 1'b0; end else begin audio_sck_d <= audio_sck; audio_ws_d <= audio_ws; end end

对于如下模块的分析:

//-----------------------------------------------
//主时钟clk上升沿到来之前,sck_neg,audio_sck_d,audio_sck 均为0 上身沿到来的时候,audio_sck_d, audio_sck信号的值进行更新,从0-1,此时并不满足if(audio_sck_d & audio_sck)的要求
//因此,第一个主时钟clk上升沿之后,sck_neg的值依旧保持为0, 下一个主时钟clk上升沿到来之前,audio_sck_d, audio_sck,的值为1,满足if(audio_sck_d & audio_sck)的要求,因此,在第二个clk上升沿之后,sck_neg的
//的值变为1.
//监测audio_sck 信号的下降沿 //疑问:为什么不采用组合逻辑的方式 //assign sck_neg = audio_sck_d & ~audio_sck ; reg sck_neg = 0; always @(posedge clk or posedge reset) begin if(reset) sck_neg <= 1'b0; else if (audio_sck_d & audio_sck) sck_neg <= 1'b1; else sck_neg <= 1'b0; end