手撕代码——2022乐鑫数字芯片提前批笔试:代码题2

手撕代码——2022乐鑫数字芯片提前批笔试:代码题2

题目:使用Verilog/SV撰写如下功能模块;求输入信号序列din在din_vld为高电平的时间段内的次小值和次小值出现的次数。接口声明如下:

module sec_min(

input clk,//时钟

input rst_n,//复位

input [9:0] din, //10bit 无符号数

input din_vld, //输入数据有效信号

output wire [9:0] dout, //次小值

output wire [8:0] cnt //次小值出现的次数。溢出时重新计数

);

verilog程序如下:

module sec_min(

input clk,//时钟

input rst_n,//复位

input [9:0] din, //10bit 无符号数

input din_vld, //输入数据有效信号

output wire [9:0] dout, //次小值

output wire [8:0] cnt //次小值出现的次数。溢出时重新计数

);

reg [9:0] data_temp;
// 缓存上个周期信号
always @(posedge clk ) begin
    if(!rst_n) begin
        data_temp<=0;
    end
    else if(din_vld)begin
        data_temp<=dout;
    end
    else begin
        data_temp<=0;
    end
end

reg [9:0] data_min;
reg [9:0] pre_data_min;
reg start;

//min
always @(posedge clk) begin
    if(!rst_n) begin
        data_min<=9'd0;
        start<=1'b1;
    end
    else if(start&&din_vld)begin
       data_min<=din;
       start<=1'b0;
    end
    else if(din_vld)begin
        if (data_min<din) begin
            data_min<=data_min;
        end
        else begin
            data_min<=din;
        end
    end
    else begin
        data_min<=0;
        start<=1'b1;
    end
end

//pre_min
reg [8:0]count;
reg second;
always @(posedge clk) begin
    if (!rst_n) begin
        pre_data_min<=0;
        second<=1'b0;
        count<=9'd0;
    end
    else if(start&&din_vld)begin
        second<=1'b1;
        pre_data_min<=din;
    end
    else if (second&&(~start)&&din_vld) begin
        if (data_temp<din) begin
            pre_data_min<=din;
            count<=9'd1;
            second<=1'b0;
        end
        else begin
            pre_data_min<=data_temp;
            count<=9'd1;
            second<=1'b0;
        end
    end
    else if (din_vld) begin
        if (din==pre_data_min) begin
            count<=count+1'b1;
            pre_data_min<=pre_data_min;
        end
        else if (din>pre_data_min) begin
            count<=count;
            pre_data_min<=pre_data_min;
        end
        else if (din<data_min) begin
            pre_data_min<=data_min;
            count<=9'd1;
        end
        else if (din==data_min) begin
            count<=count;
            pre_data_min<=pre_data_min;
        end
        else begin
            pre_data_min<=din;
            count<=9'd1;
        end
    end
    else begin
        pre_data_min<=0;
        second<=1'b0;
        count<=9'd0;
    end
end
    assign dout =pre_data_min;
    assign cnt =count;

endmodule

仿真结果如下:


由于TB的数据是按照clk的上升沿变化的,看的时候要往后看一个周期才有效。结果是OK的。

TB可以自己写然后测试。

posted @ 2022-03-29 20:57  passchen  阅读(181)  评论(0编辑  收藏  举报