手撕代码——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
仿真结果如下: