← 2022 · 乐鑫科技 笔试

推荐答案 测试一下

使用 v/sv 编写如下功能模块,求输入信号序列 din 在 din_vld 为高电平的时间段内的次小值与次小值出现的次数

编程题 中等 笔试真题

参考答案

使用Verilog/SystemVerilog设计模块,实现输入有效数据序列中次小值及其出现次数的统计。模块输入:时钟clk、复位rst_n、数据din、有效标志din_vld;输出:次小值sec_min、次数sec_cnt(可附加有效标志sec_vld)。内部使用三个寄存器:min1(最小值)、min2(次小值)、cnt1(最小值计数)、cnt2(次小值计数)。初始时,min1和min2置为最大值(如'b111...1),cnt1和cnt2清零。每个时钟上升沿,若rst_n有效则复位;否则当din_vld为高时,按如下逻辑更新: 1. 若din < min1,则min2 <= min1,cnt2 <= cnt1,min1 <= din,cnt1 <= 1。 2. 若din == min1,则cnt1 <= cnt1 + 1。 3. 若din > min1且din < min2,则min2 <= din,cnt2 <= 1。 4. 若din == min2,则cnt2 <= cnt2 + 1。 5. 其他情况不更新。 最后,sec_min <= min2,sec_cnt <= cnt2。需注意:若仅有一个有效数据或所有数据相同,则min2保持为初始最大值,cnt2为0,此时可输出sec_vld=0表示次小值无效。易错点:边界情况下min2初始值需足够大(比任何可能数据大),否则误判;当din小于min1时,原min1及计数需正确转移到min2;对相等情况的处理避免计数丢失。时序逻辑中赋值使用非阻塞赋值,防止竞争。代码示例: always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin min1 <= {WIDTH{1'b1}}; min2 <= {WIDTH{1'b1}}; cnt1 <= 0; cnt2 <= 0; end else if (din_vld) begin if (din < min1) begin min2 <= min1; cnt2 <= cnt1; min1 <= din; cnt1 <= 1; end else if (din == min1) begin cnt1 <= cnt1 + 1; end else if (din < min2) begin min2 <= din; cnt2 <= 1; end else if (din == min2) begin cnt2 <= cnt2 + 1; end end end 此外,可增加输出有效标志:assign sec_vld = (cnt2 != 0);

涉及知识点

  • 状态机与比较器设计
  • 时序逻辑非阻塞赋值
  • 边界条件与初始化处理
  • Verilog/SystemVerilog模块编写
  • 有限状态数据流处理
← 上一题
登录后反馈错题
下一题 →