阶段4-练习一

题目:

系统时钟是100M,dout的依次如下变化:

第一阶段时间是20us,此时dout周期性输出10ns低电平 和 10ns 高电平脉冲,

第二阶段时间是40us,此时dout周期性输出30ns低电平 和 10ns 高电平脉冲,

第三阶段时间是100us,此时dout周期性输出90ns低电平 和 10ns 高电平脉冲,

第四阶段时间是200us,此时dout周期性输出190ns低电平 和 10ns 高电平脉冲,

然后循环

 

题目看起来有点绕,先简化一下:100M, 一个clk 周期是10ns

第一阶段 重复 1000 次,此时dout周期性输出 1 个clk 低电平 和 1个 clk 高电平脉冲,

第二阶段 重复 1000 次,此时dout周期性输出 3 个clk 低电平 和 1个 clk 高电平脉冲,

第三阶段 重复 1000 次,此时dout周期性输出 9 个clk 低电平 和 1个 clk 高电平脉冲,

第四阶段 重复 1000 次,此时dout周期性输出 19 个clk 低电平 和 1个 clk 高电平脉冲,

然后循环

 

 

该题目就有点像之前阶段2中的练习题了,关键点:

(1)、需要引入两个变量 x 和 y , x是一个最小周期需多少个clk,y 是 dout 变高 点  和 变低点

(2)、需要三个计数器 ,计数器cnt0, 是对最小周期clk进行数数;计数器cnt1, 是对 重复最小周期 数数, 也就是1000次;计数器cnt2分别指示四个阶段

 

  1 module test_cnt(
  2                     clk        ,
  3                     rst_n    ,
  4                     
  5                     dout
  6 );
  7 
  8 input             clk    ;
  9 input             rst_n;
 10 output            dout;
 11 
 12 wire             add_cnt0;
 13 wire             end_cnt0;
 14 wire             add_cnt1;
 15 wire             end_cnt1;
 16 wire             add_cnt2;
 17 wire             end_cnt2;
 18 
 19 
 20 reg             dout;
 21 reg [5-1 :0]     cnt0;
 22 reg [10-1:0]     cnt1;
 23 reg [3-1 :0]     cnt2;
 24 reg [5-1 :0]    x;
 25 reg [5-1 :0]    y;
 26 
 27 //对最小周期数clk个数
 28 always @(posedge clk or negedge rst_n)begin
 29     if(!rst_n)begin
 30         cnt0 <= 0;
 31     end
 32     else if(add_cnt0)begin
 33         if(end_cnt0)begin
 34             cnt0 <= 0;
 35         end
 36         else begin
 37             cnt0 <= cnt0 + 1;
 38         end
 39     end
 40 end
 41 
 42 assign add_cnt0 = 1;
 43 assign end_cnt0 = add_cnt0 && cnt0 == x - 1;
 44 
 45 //对最小周期循环次数 数数
 46 always @(posedge clk or negedge rst_n)begin
 47     if(!rst_n)begin
 48         cnt1 <= 0;
 49     end
 50     else if(add_cnt1)begin
 51         if(end_cnt1)begin
 52             cnt1 <= 0;
 53         end
 54         else begin
 55             cnt1 <= cnt1 + 1;
 56         end
 57     end
 58 end
 59 
 60 assign add_cnt1 = end_cnt0;
 61 assign end_cnt1 = add_cnt1 && cnt1 == 1000 - 1;
 62 
 63 //对第1阶段 、第2阶段 、第3阶段 、第4阶段,4个阶段进行数数
 64 always @(posedge clk or negedge rst_n)begin
 65     if(!rst_n)begin
 66         cnt2 <= 0;
 67     end
 68     else if(add_cnt2)begin
 69         if(end_cnt2)begin
 70             cnt2 <= 0;
 71         end
 72         else begin
 73             cnt2 <= cnt2 + 1;
 74         end
 75     end
 76 end
 77 
 78 assign add_cnt2 = end_cnt1;
 79 assign end_cnt2 = add_cnt2 && cnt2 == 4 - 1;
 80 
 81 always @(posedge clk or negedge rst_n)begin
 82     if(!rst_n)begin
 83         dout <= 0;
 84     end
 85     else if(add_cnt0 && cnt0 == y-1)begin
 86         dout <= 1;
 87     end
 88     else if(end_cnt0)begin
 89         dout <= 0;
 90     end
 91 end
 92 
 93 always @(*)begin
 94     if(cnt2 == 0)begin
 95         x = 2;
 96         y = 1;
 97     end
 98     else if(cnt2 == 1)begin
 99         x = 4;
100         y = 3;
101     end
102     else if(cnt2 == 2)begin
103         x = 10;
104         y = 9;
105     end
106     else begin
107         x = 20;
108         y = 19;
109     end
110 end
111 
112 endmodule 

测试文件:

 1 module top_sim;
 2 
 3 reg clk;
 4 reg rst_n;
 5 
 6 wire dout;
 7 
 8 `define CYCLE 10   //100MHz ,一个周期10ns
 9 
10 initial begin
11         clk = 0;
12         forever 
13         #(`CYCLE/2) clk = ~clk;
14 end
15 
16 initial begin
17         #1;
18         rst_n = 0;
19         #(`CYCLE*5);
20         rst_n = 1;
21 end
22 
23 
24 test_cnt    u1(
25                     .clk        (clk        ),
26                     .rst_n        (rst_n        ),
27                     .dout        (dout        )
28 );
29 
30 endmodule

仿真波形:太密不能看到细节,放大后看细节是对的

 

 

 

 

posted @ 2022-03-05 18:04  MyBooks  阅读(92)  评论(0)    收藏  举报