阶段四练习3

模块时钟是100M。 dout的依次如下变化:

a、第一阶段 时间是20us。此时如果din_vld出现不低于50ns的高电平脉冲,则dout输出10ns 的高电平;

b、第二阶段 时间是40us。此时如果din_vld出现不低于100ns的高电平脉冲,则dout输出10ns 的高电平;

c、第三阶段 时间是100us。此时如果din_vld出现不低于200ns的高电平脉冲,则dout输出10ns 的高电平;

d、第四阶段 时间是200us。此时如果din_vld出现不低于40ns的高电平脉冲,则dout输出10ns 的高电平;

然后循环a~d。

时序:

 

 设计关键点:

(1)、确认计数器个数:

    >> 要对din_vld进行数数,需要一个 cnt0,每个阶段数的数不一样,引入变量x;

    >>每个阶段的时间不一样,需要一个 cnt1 对其进行计数,引入变量y;

    >>有四个阶段,需要一个 cnt2 对阶段进行数数,次数为4;

    通过组合逻辑,利用阶段计数器cnt2区分分别对变量x , y 进行赋值。

(2)、当din_vld连续高电平个数不足数量时就被拉低了,此时需要将cnt0计数器清零,方便下次重新数数。

(3)、当din_vld连续高电平个数超过指定数量时,cnt0不需在进行数数,所以计数器判断条件得附加上flag_add,flag_add用于区分计数满之后就不用在计数标志。

(4)、dout输出高电平只需保持一个时钟周期。

代码:

  1 module test_cnt(
  2                     clk        ,
  3                     rst_n    ,
  4                     din_vld ,
  5                     
  6                     dout
  7 );
  8 
  9 input             clk    ;
 10 input             rst_n;
 11 input             din_vld;
 12 
 13 
 14 output            dout;
 15 
 16 wire             add_cnt0;
 17 wire             end_cnt0;
 18 wire             add_cnt1;
 19 wire             end_cnt1;
 20 wire             add_cnt2;
 21 wire             end_cnt2;
 22 
 23 reg                flag_add;
 24 reg             dout;
 25 reg [5-1 :0]     cnt0;
 26 reg [16-1:0]     cnt1;
 27 reg [3-1 :0]     cnt2;
 28 reg [5-1 :0]    x;
 29 reg [16-1:0]    y;
 30 
 31 //对din_vld 高电平进行数数
 32 always @(posedge clk or negedge rst_n)begin
 33     if(!rst_n)begin
 34         cnt0 <= 0;
 35     end
 36     else if(add_cnt0)begin
 37         if(end_cnt0)begin
 38             cnt0 <= 0;
 39         end
 40         else begin
 41             cnt0 <= cnt0 + 1;
 42         end
 43     end
 44     else begin  //如果中间din_vld数到不够数时就拉低了,计数器一定要清零,方便下次开始数数
 45         cnt0 <= 0;
 46     end
 47 end
 48 
 49 assign add_cnt0 = din_vld == 1 && flag_add == 0; //附加上flag_add条件,数到数量够时,不在对din_vld进行数数
 50 assign end_cnt0 = add_cnt0 && cnt0 == x - 1;
 51 
 52 //一个阶段的时间
 53 always @(posedge clk or negedge rst_n)begin
 54     if(!rst_n)begin
 55         cnt1 <= 0;
 56     end
 57     else if(add_cnt1)begin
 58         if(end_cnt1)begin
 59             cnt1 <= 0;
 60         end
 61         else begin
 62             cnt1 <= cnt1 + 1;
 63         end
 64     end
 65 end
 66 
 67 assign add_cnt1 = 1;    //注意开始条件不在是end_cnt0
 68 assign end_cnt1 = add_cnt1 && cnt1 == y - 1;
 69 
 70 //对第1阶段 、第2阶段 、第3阶段 、第4阶段,4个阶段进行数数
 71 always @(posedge clk or negedge rst_n)begin
 72     if(!rst_n)begin
 73         cnt2 <= 0;
 74     end
 75     else if(add_cnt2)begin
 76         if(end_cnt2)begin
 77             cnt2 <= 0;
 78         end
 79         else begin
 80             cnt2 <= cnt2 + 1;
 81         end
 82     end
 83 end
 84 
 85 assign add_cnt2 = end_cnt1;
 86 assign end_cnt2 = add_cnt2 && cnt2 == 4 - 1;
 87 
 88 always @(posedge clk or negedge rst_n)begin
 89     if(!rst_n)begin
 90         flag_add <= 0;
 91     end
 92     else if(end_cnt0)begin //数到够数量时就停止计数
 93         flag_add <= 1;
 94     end
 95     else if(din_vld == 0)begin //等到din_vld变低时,将flag_add变0,便于下次开始计数
 96         flag_add <= 0;
 97     end
 98 end
 99 
100 always @(posedge clk or negedge rst_n)begin
101     if(!rst_n)begin
102         dout <= 0;
103     end
104     else if(end_cnt0)begin //只保持一个时钟周期
105         dout <= 1;
106     end
107     else begin
108         dout <= 0;
109     end
110 end
111 
112 //四种不同阶段下,对x ,y变量进行赋值
113 always @(*)begin
114     if(cnt2 == 0)begin
115         x = 5;
116         y = 2000;
117     end
118     else if(cnt2 == 1)begin
119         x = 10;
120         y = 4000;
121     end
122     else if(cnt2 == 2)begin
123         x = 20;
124         y = 10000;
125     end
126     else begin
127         x = 4;
128         y = 20000;
129     end
130 end
131 
132 endmodule 

测试文件:关键点利用 //$urandom_range(min,max)生成min到max范围内的随机无符号整数 

  1 module top_sim;
  2 
  3 reg         clk;
  4 reg         rst_n;
  5 reg         din_vld;
  6 
  7 wire         dout;
  8 
  9 `define CYCLE 10   //100MHz ,一个周期10ns
 10 
 11 initial begin
 12         clk = 0;
 13         forever 
 14         #(`CYCLE/2) clk = ~clk;
 15 end
 16 
 17 initial begin
 18         rst_n = 0;
 19         #1;
 20         #(`CYCLE*5);
 21         rst_n = 1;
 22 end
 23 
 24 
 25 //$urandom_range(min,max)生成min到max范围内的随机无符号整数
 26 initial begin
 27         din_vld = 0;
 28         #1;
 29         #(`CYCLE*10);
 30         
 31         //第一阶段
 32         repeat(20)begin
 33             din_vld = 1; 
 34             #(`CYCLE*$urandom_range(7,8));
 35             din_vld = 0;
 36             #(`CYCLE*20);
 37             din_vld = 1;
 38             #(`CYCLE*$urandom_range(2,6));
 39             
 40             repeat(20)begin
 41                 din_vld = 0;
 42                 #(`CYCLE*10);
 43             end
 44         end
 45         
 46         //第二阶段
 47         repeat(20)begin
 48             din_vld = 1; 
 49             #(`CYCLE*$urandom_range(12,15));
 50             din_vld = 0;
 51             #(`CYCLE*20);
 52             din_vld = 1;
 53             #(`CYCLE*$urandom_range(10,12));
 54             
 55             repeat(20)begin
 56                 din_vld = 0;
 57                 #(`CYCLE*10);
 58             end
 59         end
 60         
 61         //第三阶段
 62         repeat(100)begin
 63             din_vld = 1; 
 64             #(`CYCLE*$urandom_range(22,15));
 65             din_vld = 0;
 66             #(`CYCLE*20);
 67             din_vld = 1;
 68             #(`CYCLE*$urandom_range(18,21));
 69             
 70             repeat(100)begin
 71                 din_vld = 0;
 72                 #(`CYCLE*10);
 73             end
 74         end
 75         
 76         //第四阶段
 77         repeat(100)begin
 78             din_vld = 1; 
 79             #(`CYCLE*$urandom_range(5,7));
 80             din_vld = 0;
 81             #(`CYCLE*20);
 82             din_vld = 1;
 83             #(`CYCLE*$urandom_range(3,5));
 84             
 85             repeat(100)begin
 86                 din_vld = 0;
 87                 #(`CYCLE*10);
 88             end
 89         end
 90 
 91 end
 92 
 93 test_cnt        u1_inist(
 94                             .clk(clk),
 95                             .rst_n(rst_n),
 96                             .din_vld(din_vld),
 97                             
 98                             .dout(dout)
 99                         );
100 
101 
102 endmodule

仿真波形:

 

 

查看具体细节:

 

posted @ 2022-03-15 11:17  MyBooks  阅读(82)  评论(0)    收藏  举报