练习题目: 当收到en信号之后,
a,隔1个时钟周期,dout输出4个高电平,然后
b,隔1个时钟周期,dout输出3个高电平,然后
c,隔1个时钟周期,dout输出2个高电平,然后
d,隔1个时钟周期,dout输出1个高电平,然后
第一关键点,隔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
仿真代码:
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
仿真波形: