赞
踩
我看有网友用了其它方法实现,今天就试了用状态机实现,可是统计次小值次数还没想好怎么弄,改天补充吧........
1、题目要求
使用Verilog/SV撰写如下功能模块;求输入信号序列din在din_vld为高电平的时间段内的次小值和次小值
出现的次数。接口信号如下,
module sec_min(
input clk, //时钟信号
input rst_n, //复位信号
input [9:0] din, //10bit无符号数
input din_vld, //输入数据有效信号
output [9:0] dout, //次小值
output [8:0] cnt //次小值出现的次数,溢出时重新计数
);endmodule
2、根据题目要求编写程序,目前只实现了找出次小值、还没实现统计次小值次数,改天再来补充
- module sec_min_mod(
- input wire clk,
- input wire rst_n,
- input wire [9:0] din,//10bit number
- input wire din_vld, // valid
- output reg [9:0] dout,// 次小之
- output reg [8:0] cnt // 次小值次数
- );
-
- reg [9:0] din_reg0;
- reg [9:0] sec_min;
- reg [9:0] fir_min ;
-
-
- reg [1:0] din_vld_reg;
- wire din_neg_flag;
- reg [4:0] current_state;
- reg [4:0] next_state;
-
-
-
-
- parameter IDLE = 5'b00001,
- C_IDLE = 5'b00010,
- C0 = 5'b00100,
- C1 = 5'b01000,
- C2 = 5'b10000;
-
-
-
-
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n)
- din_vld_reg <= 2'd0;
- else
- din_vld_reg <= {din_vld_reg[0],din_vld};
- end
-
- assign din_neg_flag = (din_vld_reg[1] && ~din_vld_reg[0])? 1'b1:1'b0;
-
-
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n)
- din_reg0 <= 10'd0;
- else
- din_reg0 <= din;
- end
-
-
-
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- current_state <= IDLE;
- else
- current_state <= next_state;
-
-
- always @(*) begin
- case(current_state)
- IDLE: if(din_vld)
- next_state = C_IDLE;
- else
- next_state =IDLE;
- C_IDLE: next_state =C0;
- C0: next_state = C1;
- C1: if(din_neg_flag)
- next_state = C2;
- else
- next_state = C1;
- C2: next_state =IDLE;
- default: next_state =IDLE;
- endcase
- end
-
-
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) begin
- fir_min <= 10'd0;
- sec_min <= 10'd0;
- end
- else if (current_state == C0) begin
- if (din <= din_reg0) begin
- fir_min <= din;
- sec_min <= din_reg0;
- end
- else begin
- fir_min <= din_reg0;
- sec_min <= din;
- end
- end
- else if(current_state == C1) begin
- if( sec_min <= din) begin
- fir_min <= fir_min;
- sec_min <= sec_min;
- end
- else begin
- if(din >= fir_min) begin
- fir_min <= din;
- sec_min <= sec_min;
- end
- else begin
- fir_min <= din;
- sec_min <= fir_min;
- end
- end
- end
- else begin
- fir_min <= fir_min;
- sec_min <= sec_min;
- end
- end
-
-
- //输出次小值
-
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n)
- dout <= 10'd0;
- else if (current_state == C2)
- dout <= sec_min;
- else
- dout <= dout;
- end
-
-
-
- endmodule
3、tb仿真
- `timescale 1ns/1ps
- module tb_expressif();
-
- reg clk ;
- reg rst_n;
- reg [9:0] din;
- reg din_vld;
- wire [9:0] dout;
- wire [8:0] cnt;
- integer i;
-
- initial begin
- clk =0;
- rst_n = 1'b0;
- din = 10'd0;
- din_vld = 1'b0;
- #100;
- rst_n =1;
- #20;
- din_vld = 1'b1;
- for(i=0;i< 20;i=i+1) begin
- @(posedge clk) begin
- din = {$random} % 5;
- end
- end
- din_vld =1'b0;
- #100;
- //$stop;
- end
-
- always #5 clk = ~clk;
-
- sec_min_mod sec_min_inst(
- .clk(clk),
- .rst_n(rst_n),
- .din(din),//10bit number
- .din_vld(din_vld), // valid
- .dout(dout),// 次小之
- .cnt(cnt) // 次小值次数
- );
-
-
- endmodule
4、modelsim 波形图
根据波形所示,输入数据为0,1,2,3,4 ,最好dout正确输出次小值1,仿真正确,用状态机,统计次数还未想到怎么处理......就这样吧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。