常用电路基本有下列这些:
D触发器
移位寄存器
边沿检测电路
多路复用器
多路解复用器
计数器
奇偶分频器
D触发器
1 always @ (posedge clk or negedge rst_n) begin 2 if(!rst_n) 3 dout<=1'b0; 4 else 5 dout<=din; 6 end
移位寄存器:
1 reg [7:0] dout;
2 always @ (posedge clk or negedge rst_n) begin
3 if(!rst_n)
4 dout<=8'd0;
5 else
6 dout<={dout[6:0],din};
7 end
RTL视图:
边沿检测电路:
1 reg din_ff1;
2 reg din_ff2;
3 always @ (posedge clk or negedge rst_n) begin
4 if(!rst_n) begin
5 din_ff1<=1'b0;
6 din_ff2<=1'b0;
7 end
8 else begin
9 din_ff1<=din;
10 din_ff2<=din_ff1;
11 end
12 end
13
14 assign raising_edge<=din_ff1 &(~din_ff2);
15 assign falling_edge<=din_ff2 &(~din_ff1);
16 assign double_edge<=din_ff1 ^din_ff2;
多路复用器:有多个输入,单个输出通过地址选择线选择一个输入对应一个输出,输出用DFF同步一下
1 reg dout; 2 always @ (posedge clk) begin 3 case(addr) 4 2'b00: dout<=din_1; 5 2'b01: dout<=din_2; 6 2'b10: dout<=din_3; 7 2'b11: dout<=din_4; 8 endcase 9 end
RTL视图:
多路解复用器:是多路复用器的逆向过程,只有一个输入,多个输出,通过地址选择线,选择一个输入对应的一个输出
1 reg dout_1; 2 reg dout_2; 3 reg dout_3; 4 reg dout_4; 5 always @ (posedge clk) begin 6 case(addr) 7 2'b00: dout_1<=din; 8 2'b01: dout_2<=din; 9 2'b10: dout_3<=din; 10 2'b11: dout_4<=din; 11 endcase 12 end
RTL视图:
计数器:通常需要指定模n,则需要在最大计数值时变为0,如果是全模计数器则不需这一步,用logn/log2可以知道需要几位二进制数,若不是全模,则取整。
1 //模6计数器 2 reg dout; 3 always @ (posedge clk or negedge rst_n) begin 4 if(!rst_n) 5 dout<=3'd0; 6 else if(dout>=3'd5) 7 dout<=3'd0; 8 else 9 dout<=dout+1'b1; 10 end
* 格雷码计数器:先进行二进制计数,再将二进制转换为格雷码
格雷码排列:第一次翻转最低位,第二次翻转从左边起最靠近1的那个0,重复以上步骤
1 reg [4:0] cnt; 2 always @ (posedge clk or negedge rst_n) begin 3 if(!rst_n) 4 cnt<=5'd0; 5 else 6 cnt<=cnt+1'b1; 7 end 8 9 reg [4:0] gray_tmp; 10 reg bin_tmp; 11 always (*) begin 12 gray_tmp[4]=cnt[4]; 13 for(i=0;i<4;i=i+1) 14 gray_tmp[i]=cnt[i]^cnt[i+1]; 15 end 16 17 reg [4:0] gray_out; 18 always @ (posedge clk or negedge rst_n) begin 19 if(!rst_n) 20 gray_out<=5'd0; 21 else 22 gray_out<=gray_tmp; 23 end
奇偶分频器:是计数电路与置位电路的组合,通常是n分频就用模n计数器,计数到n的一半时分频信号状态变换
1 //6分频器 2 reg [2:0] cnt; 3 always @ (posedge clk or negedge rst_n) begin 4 if(!rst_n) 5 cnt<=3'd0; 6 else if(cnt>=3'd5) 7 cnt<=3'd0; 8 else 9 cnt<=cnt+1'b1; 10 end 11 12 reg dou_div; 13 always @ (posedge clk or negedge rst_n) begin 14 if(!rst_n) 15 dout_div<=1'b0; 16 else if(cnt>=3'd3) 17 dout_div<=1'b1; 18 else 19 dout_div<=1'b0; 20 end
当n是全模的状态时,用最高位即可表示n分频信号
1 //模8计数器 2 reg [2:0] cnt; 3 always @ (posedge clk or negedge rst_n) begin 4 if(!rst_n) 5 cnt<=3'd0; 6 else 7 cnt<=cnt+1'b1; 8 end 9 10 assign dout_div=cnt[2];
奇数分频时采用错位或的方式
1 //7分频 2 reg [2:0] cnt; 3 always @ (posedge clk or negedge rst_n) begin 4 if(!rst_n) 5 cnt<=3'd0; 6 else if(cnt>=3'd6) 7 cnt<=3'd0; 8 else 9 cnt<=cnt+1'b1; 10 end 11 12 reg clk_pos; 13 always @ (posedge clk or negedge rst_n) begin 14 if(!rst_n) 15 clk_pos<=1'b0; 16 else if(cnt>=3'd0 && cnt<3'd3) 17 clk_pos<=1'b1; 18 else 19 clk_pos<=1'b0; 20 end 21 22 reg clk_neg; 23 always @ (negedge clk or negedge rst_n) begin 24 if(!rst_n) 25 clk_neg<=1'b0; 26 else if(cnt>=3'd1 && cnt<3'd4) 27 clk_neg<=1'b1; 28 else 29 clk_neg<=1'b0; 30 end 31 32 assign clk_div=clk_pos | clk_neg;