计数器练习11

练习题目: 当收到en信号之后,

a,隔1个时钟周期,dout输出4个高电平,然后

b,隔1个时钟周期,dout输出3个高电平,然后

c,隔1个时钟周期,dout输出2个高电平,然后

d,隔1个时钟周期,dout输出1个高电平,然后

计数器练习11

第一关键点,隔1隔时钟,dout输出 x 个高电平,需一个计数器cnt0,引入了一个“x”变量,因为是在不同时间段赋不同值,说明该计数器可以重复利用

第二关键点,有a b c d 四轮,在需一个计数器cnt1,计数4轮

第三关键点,什么时候开始计数,收到en之后开始计数,增加一个信号进来 flag_add , 那什么时候结束,四轮结束时,计数器停止

第四关键点, dout什么时候为高,什么时候为低

代码如下:

  1 module cnt_test(
  2                 clk,
  3                 rst_n,
  4                 en,
  5                 dout
  6 );
  7 
  8 input     clk;
  9 input     rst_n;
 10 input      en;
 11 
 12 output    dout;
 13 
 14 reg     dout;
 15 reg     flag_add;
 16 
 17 reg [3:0] cnt0;
 18 reg [3:0] cnt1;
 19 reg [3:0] x;
 20 
 21 wire add_cnt0;
 22 wire end_cnt0;
 23 
 24 wire add_cnt1;
 25 wire end_cnt1;
 26 
 27 
 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 = flag_add;
 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 == 4 - 1;
 62 
 63 always @(posedge clk or negedge rst_n)begin
 64     if(!rst_n)begin
 65         flag_add <= 0;
 66     end
 67     else if(en == 1)begin
 68         flag_add <= 1;
 69     end
 70     else if(end_cnt1)begin
 71         flag_add <= 0;
 72     end
 73 end
 74 
 75 always @(*)begin
 76     if(cnt1 == 0)begin
 77         x = 5;
 78     end
 79     else if(cnt1 == 1)begin
 80         x = 4;
 81     end
 82     else if(cnt1 == 2)begin
 83         x = 3;
 84     end
 85 /*    
 86     else if(cnt1 == 3)begin  //这里可以不添加if判断语句 ,否则必须将if else 补全,在其他状态时,一定要确保x有个确定值
 87         x = 2;
 88     end
 89 */
 90     else if(cnt1 == 3)begin
 91         x = 2;
 92     end
 93     else begin  //if else 补全 ,以确保在其他状态时,x始终都能确定某一个固定值
 94         x = 0; 
 95     end
 96     
 97 end
 98 
 99 always @(posedge clk or negedge rst_n)begin
100     if(!rst_n)begin
101         dout <= 0;
102     end
103     else if(add_cnt0 && cnt0 == 1-1)begin //对某个点进行赋值,记得用“-1”写法
104         dout <= 1;
105     end
106     else if(end_cnt0) begin    //对某个点进行赋值
107         dout <= 0;    
108     end
109 end
110 
111 endmodule

仿真代码:

计数器练习11
 1 module top_sim();
 2 
 3 reg clk;
 4 reg rst_n;
 5 reg en;
 6 wire dout;
 7 
 8 parameter CLK_CYCLE    = 20;
 9 
10 initial begin
11     clk = 0;
12     forever begin
13         #(CLK_CYCLE/2);
14         clk = ~clk;
15     end
16         
17 end
18 
19 initial begin
20     #1;
21     rst_n = 0;
22     #(CLK_CYCLE*2);
23     rst_n = 1;
24 end
25 
26 initial begin
27      #1;
28     en = 0;
29 
30     #(100*CLK_CYCLE);
31     en = 1;
32     #(1*CLK_CYCLE);
33     en = 0;
34     #(100*CLK_CYCLE);
35     en = 1;
36     #(1*CLK_CYCLE);
37     en = 0;
38 end
39 
40 
41 cnt_test        u1(    
42                         .clk(clk),
43                         .rst_n(rst_n),
44                         .en(en),
45                         .dout(dout)
46                         
47 );
48 
49 endmodule 
View Code

仿真波形:

计数器练习11

 

上一篇:数组翻转


下一篇:uCOS-III 学习记录(11)——任务管理