⭐
使用頻度の高い部品のHDL記述例 -カウンタ-
カウンタは、あるパルスの数を数えたり、タイミングを作るのに使ったり、様々なところで使われる基本的な回路と言えます。
使い方により様々な書き方が出来ますが、いくつか記述例を挙げます。
例1
一番単純なカウンタの記述例です。クロックを数えるだけのものです。
VHDL
process (RST,CLK) begin
if (RST = '1')then
counter <= (others => '0');
elsif (CLK'event and CLK = '1') then
counter <= counter + 1;
end if;
end process;
verilog
always@(posedge RST or posedge CLK) begin
if (RST == 1'b1) begin
counter <= 'd0;
end else begin
counter <= counter + 1;
end
end
この場合、最大値まで数えたら0に戻って繰り返し動作します。
例2
例1はカウントアップしていきますが、カウントダウンしていく記述例です。(8bitの例)
この場合は、0まで数えたら最大値に戻って繰り返し動作します。
VHDL
process (RST,CLK) begin
if (RST = '1')then
counter <= (others => '1');
elsif (CLK'event and CLK = '1') then
counter <= counter - 1;
end if;
end process;
verilog
always@(posedge RST or posedge CLK) begin
if (RST == 1'b1) begin
counter <= 8'hFF;
end else begin
counter <= counter - 1;
end
end
verilogの場合、全bit1の代入はbit数指定して最大値を入れることになり、データ幅をパラメータにした時にちょっと厄介になります。
SystemVerilogの書き方だと簡単に出来ます。
SystemVerilog
always@(posedge RST or posedge CLK) begin
if (RST == 1'b1) begin
counter <= '1;
end else begin
counter <= counter - 1;
end
end
例3
今度はパルス信号を数えて、最大値100になったら数えるのを止めるカウンタの例です。
VHDL
process (RST,CLK) begin
if (RST = '1')then
counter <= (others => '0');
elsif (CLK'event and CLK = '1') then
if (pulse = '1') then
if (counter < 100) then
counter <= counter + 1;
end if;
end if;
end if;
end process;
verilog
always@(posedge RST or posedge CLK) begin
if (RST == 1'b1) begin
counter <= 'd0;
end else if (pulse == 1'b1) begin
if (counter < 100) begin
counter <= counter + 1;
end
end
end
例4
最大値99からパルス信号を減らしながら数えて、0になったら最大値に戻るカウンタの例です。最大値99なので7bitあればよいです。
VHDL
process (RST,CLK) begin
if (RST = '1')then
counter <= "1100011";--99
elsif (CLK'event and CLK = '1') then
if (pulse = '1') then
if (counter = 0) then
counter <= "1100011";--99
else
counter <= counter - 1;
end if;
end if;
end if;
end process;
verilog
always@(posedge RST or posedge CLK) begin
if (RST == 1'b1) begin
counter <= 7'd99;
end else if (pulse == 1'b1) begin
if (counter == 0) begin
counter <= 7'd99;
end else begin
counter <= counter - 1;
end
end
end
最大値が固定値であるなら、定数を宣言して、それを使用する方がよいと思います。
上記の例では、bit幅をあまり意識しないでよい書き方をしている箇所があります。bit幅や最大値などをパラメータ化したカウンタをモジュール化してあちこちで使用するといったこともありますので、そのあたりは適宜調整いただくのがよいかと思います。
Discussion