需用到两个计数器,cnt0计数器一轮的结束, cnt1计数循环3轮
需要三个变量x,y,z ,x: 是cnt0计数器的结束条件 , y 是 dout变为0的条件, z 是dout要赋的值
1 module cnt_test( 2 clk, 3 rst_n, 4 en1, 5 en2, 6 en3, 7 dout 8 ); 9 10 input clk; 11 input rst_n; 12 input en1; 13 input en2; 14 input en3; 15 16 output [2:0] dout; 17 18 reg [2:0] dout; 19 reg flag_add; 20 21 reg [3:0] cnt0; 22 reg [3:0] cnt1; 23 reg [3:0] x; 24 reg [3:0] y; 25 reg [3:0] z; 26 reg [3:0] flag_sel; 27 28 wire add_cnt0; 29 wire end_cnt0; 30 31 wire add_cnt1; 32 wire end_cnt1; 33 34 always @(posedge clk or negedge rst_n)begin 35 if(!rst_n)begin 36 cnt0 <= 0; 37 end 38 else if(add_cnt0)begin 39 if(end_cnt0)begin 40 cnt0 <= 0; 41 end 42 else begin 43 cnt0 <= cnt0 + 1; 44 end 45 end 46 end 47 48 assign add_cnt0 = flag_add; 49 assign end_cnt0 = add_cnt0 && cnt0 == x - 1; 50 51 always @(posedge clk or negedge rst_n)begin 52 if(!rst_n)begin 53 cnt1 <= 0; 54 end 55 else if(add_cnt1)begin 56 if(end_cnt1)begin 57 cnt1 <= 0; 58 end 59 else begin 60 cnt1 <= cnt1 + 1; 61 end 62 end 63 end 64 65 assign add_cnt1 = end_cnt0; 66 assign end_cnt1 = add_cnt1 && cnt1 == 3 - 1; 67 68 always @(posedge clk or negedge rst_n)begin 69 if(!rst_n)begin 70 flag_sel <= 0; 71 end 72 else if(en1)begin 73 flag_sel <= 0; 74 end 75 else if(en2)begin 76 flag_sel <= 1; 77 end 78 else if(en3)begin 79 flag_sel <= 2; //flag_sel 取值尽量从0,1, 2 ,这里不需要flag_sel <= 3,这样也可以节省资源 80 end 81 end 82 83 always @(posedge clk or negedge rst_n)begin 84 if(!rst_n)begin 85 flag_add <= 0; 86 end 87 else if(en1 || en2 || en3)begin 88 flag_add <= 1; 89 end 90 else if(end_cnt1)begin 91 flag_add <= 0; 92 end 93 end 94 95 always @(posedge clk or negedge rst_n)begin 96 if(!rst_n)begin 97 dout <= 0; 98 end 99 else if(add_cnt0 && cnt0 == y-1)begin 100 dout <= z; 101 end 102 else if(end_cnt0)begin 103 dout <= 0; 104 end 105 end 106 107 always @(*)begin 108 if(flag_sel == 0)begin 109 x = 4; 110 y = 1; 111 z = 3; 112 end 113 else if (flag_sel == 1)begin 114 x = 3; 115 y = 1; 116 z = 2; 117 end 118 else begin //此处省去flag_sel == 2, 并去掉了if,避免被综合成锁存器 119 x = 2; 120 y = 1; 121 z = 1; 122 end 123 end 124 125 endmodule
测试文件:
1 module top_sim(); 2 3 reg clk; 4 reg rst_n; 5 reg en1; 6 reg en2; 7 reg en3; 8 wire dout; 9 10 parameter CLK_CYCLE = 20; 11 12 initial begin 13 clk = 0; 14 forever begin 15 #(CLK_CYCLE/2); 16 clk = ~clk; 17 end 18 19 end 20 21 initial begin 22 #1; 23 rst_n = 0; 24 #(CLK_CYCLE*2); 25 rst_n = 1; 26 end 27 28 initial begin 29 #1; 30 en1 = 0; 31 en2 = 0; 32 en3 = 0; 33 34 #(10*CLK_CYCLE); 35 en1 = 1; 36 #(1*CLK_CYCLE); 37 en1 = 0; 38 #(12*CLK_CYCLE); 39 en2 = 1; 40 #(1*CLK_CYCLE); 41 en2 = 0; 42 #(12*CLK_CYCLE); 43 en3 = 1; 44 #(1*CLK_CYCLE); 45 en3 = 0; 46 end 47 48 49 cnt_test u1( 50 .clk(clk), 51 .rst_n(rst_n), 52 .en1(en1), 53 .en2(en2), 54 .en3(en3), 55 .dout(dout) 56 57 ); 58 59 endmoduleView Code
仿真波形: