当收到en = 1时 ,执行以下操作:
a. 间隔1个时钟周期后,dout产生宽度为 3 个时钟周期的高电平脉冲,然后
b. 间隔2个时钟周期后,dout产生宽度为 4 个时钟周期的高电平脉冲,然后
c. 间隔3个时钟周期后,dout产生宽度为5 个时钟周期的高电平脉冲,然后
d. 间隔4个时钟周期后,dout产生宽度为 6个时钟周期的高电平脉冲,结束。
波形如下:
第一关键点,间隔时钟,dout输出 x 个高电平,需一个计数器cnt0,引入了一个“x”变量,因为是在不同时间段赋不同值,说明该计数器可以重复利用
第二关键点,有a b c d 四轮,在需一个计数器cnt1,计数4轮
第三关键点,什么时候开始计数,收到en之后开始计数,增加一个信号进来 flag_add , 那什么时候结束,四轮结束时,计数器停止
第四关键点, dout什么时候为高,什么时候为低,引入变量Y,也就是间隔Y个时钟
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 reg [3:0] y; 21 22 wire add_cnt0; 23 wire end_cnt0; 24 25 wire add_cnt1; 26 wire end_cnt1; 27 28 29 always @(posedge clk or negedge rst_n)begin 30 if(!rst_n)begin 31 cnt0 <= 0; 32 end 33 else if(add_cnt0)begin 34 if(end_cnt0)begin 35 cnt0 <= 0; 36 end 37 else begin 38 cnt0 <= cnt0 + 1; 39 end 40 end 41 end 42 43 assign add_cnt0 = flag_add; 44 assign end_cnt0 = add_cnt0 && cnt0 == x - 1; 45 46 47 always @(posedge clk or negedge rst_n)begin 48 if(!rst_n)begin 49 cnt1 <= 0; 50 end 51 else if(add_cnt1)begin 52 if(end_cnt1)begin 53 cnt1 <= 0; 54 end 55 else begin 56 cnt1 <= cnt1 + 1; 57 end 58 end 59 end 60 61 assign add_cnt1 = end_cnt0; 62 assign end_cnt1 = add_cnt1 && cnt1 == 4 - 1; 63 64 always @(posedge clk or negedge rst_n)begin 65 if(!rst_n)begin 66 flag_add <= 0; 67 end 68 else if(en == 1)begin 69 flag_add <= 1; 70 end 71 else if(end_cnt1)begin 72 flag_add <= 0; 73 end 74 end 75 76 always @(*)begin 77 if(cnt1 == 0)begin 78 x = 4; 79 y = 1; 80 end 81 else if(cnt1 == 1)begin 82 x = 6; 83 y = 2; 84 end 85 else if(cnt1 == 2)begin 86 x = 8; 87 y = 3; 88 end 89 /* 90 else if(cnt1 == 3)begin //这里可以不添加if判断语句 ,否则必须将if else 补全,在其他状态时,一定要确保x有个确定值 91 x = 2; 92 end 93 */ 94 else if(cnt1 == 3)begin 95 x = 10; 96 y = 4; 97 end 98 else begin //if else 补全 ,以确保在其他状态时,x始终都能确定某一个固定值 99 x = 0; 100 y = 0; 101 end 102 103 end 104 105 always @(posedge clk or negedge rst_n)begin 106 if(!rst_n)begin 107 dout <= 0; 108 end 109 else if(add_cnt0 && cnt0 == y-1)begin //对某个点进行赋值,记得用“-1”写法 110 dout <= 1; 111 end 112 else if(end_cnt0) begin //对某个点进行赋值 113 dout <= 0; 114 end 115 end 116 117 endmodule
仿真波形: