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

筛选最小值---verilog

Posted on 2018-12-28 13:38  沉默改良者  阅读(2026)  评论(0编辑  收藏  举报

筛选最小值---verilog

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: chensimin
// 
// Create Date: 2018/12/07 15:30:20
// Design Name: 
// Module Name: aes_dru
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module aes_dru (

    input       wire      clk,
    input       wire      rst

    );


//---------------------------------------------------------------------

//计数器,方便对生成的序列进行定位,仿真时,生成信号源的好思路

reg [8:0] cnt_for_serin = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        cnt_for_serin <= 0;
    else 
        cnt_for_serin <= cnt_for_serin + 1'b1;
end

//---------------------------------------------------------------------

//生成serin序列

reg serin = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        serin <= 0;
    else 
    begin
        case(cnt_for_serin)
            5 : serin <= 1'b1;
            12: serin <= 1'b0;
            20: serin <= 1'b1;
            40: serin <= 1'b0;
            70: serin <= 1'b1;
            default: serin <= serin;
        endcase
    end
end

//---------------------------------------------------------------------

reg  [2:0] inffs = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        inffs <= 0;
    else 
        inffs <= {inffs[1:0], serin};
end 

//---------------------------------------------------------------------

//边沿检测可以检测上升沿和下降沿

assign edge_detect = ^inffs[2:1];

//---------------------------------------------------------------------

//计算出两个脉冲之间的时钟周期

reg  [9:0] min_cntr = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        min_cntr <= 0;
    else if(edge_detect)
        min_cntr <= 0;
    else
        min_cntr <= min_cntr + 1;
end 

//---------------------------------------------------------------------

//对边沿脉冲进行计数

reg [9:0] update_cntr = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        update_cntr <= 0;
    else if(edge_detect)
        update_cntr <= update_cntr + 1'b1;
end

//---------------------------------------------------------------------

//当边沿脉冲数满后,产生一个叫update_min的脉冲

wire   update_min;

assign update_min = update_cntr == {10{1'b1}};

//---------------------------------------------------------------------

//当updata_min脉冲到来时,最小值设定为全1,new_min成为更新min_capture的条件

reg [9:0] min_capture = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        min_capture <= 0;
    else if(edge_detect)
    begin
        if(update_min)
            min_capture <= {10{1'b1}};
        else if(new_min)
            min_capture <= min_cntr;
    end
end

assign new_min = min_cntr < min_capture;

//---------------------------------------------------------------------

//当结束完一个计数周期后,用min_hold 锁存本周期的最小值

reg  [9:0] min_hold = 0 ;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        min_hold <= 0;
    else if (edge_detect & update_min)
        min_hold <= min_capture;
end 

//---------------------------------------------------------------------

//

reg  [9:0] sample_cntr = 0;

always @ (posedge clk or posedge rst)
begin
    if(rst)
        sample_cntr <= 0;
    else if (edge_detect | (sample_cntr >= min_hold))
        sample_cntr <= 0;
    else
        sample_cntr <= sample_cntr + 1;
end       

//---------------------------------------------------------------------


endmodule


/*

add_force {/aes_dru/clk} -radix hex {1 0ns} {0 25000ps} -repeat_every 50000ps
add_force {/aes_dru/rst} -radix hex {1 0ns} {0 100ns}


*/

仿真结果: