随着时钟,一步一步对唯一的‘1’进行循环移位,例如位宽为4的情况:
0001,0010,0100,1000,0100,0010,0001,0010,……
这时候,需要用条件语句区分所处的位置,有时候是左移,有时候是右移。
本文还特意将位宽写成了参数parameter形式,这样仅在测试程序里修改一个数,就可以很方便地实现不同位宽下的环形计数器。
主程序:
module ring#
(parameter WIDTH = 4)
(input Rst, input Clk, output reg [WIDTH:0] Result);
reg [WIDTH:0] Count;
always @(posedge Clk or posedge Rst)
begin
if (Rst)
begin
Result <= 'b1;
Count <= 'b0;
end
else if (Count <= WIDTH-2)
begin
Result <= Result << 1;
Count <= Count + 1;
end
else if (Count <= 2*(WIDTH-2))
begin
Result <= Result >> 1;
Count <= Count + 1;
end
else
begin
Result <= 'b1;
Count <= 'b0;
end
end
endmodule
以位宽为8为例,测试程序:
`timescale 1 ns/ 1 ns
module tb_ring();
reg Clk, Rst;
wire [8-1:0] Result;
ring#(.WIDTH(8)) U1(.Rst(Rst), .Clk(Clk), .Result(Result));
always
begin
#5 Clk <= ~Clk;
end
initial
begin
Clk <= 0;
Rst <= 1;
#13 Rst <=0;
#200 $stop;
end
endmodule
结果如下: