ChaN さんの「AVRでタッチセンサ」を見て思った。
5x5=25点ぐらいになると、CPU より FPGA のほうが適任なのではないか?
- 単純な並列処理
- 結構高速(100nsオーダ)
で。恐らくカウンタとコンパレータを verilog で書ければよさげ。
コンパレータ
以下、ウェブで見つけたもの。感謝。
[p.69] 2つの2進数の値のどちらが大きいか、あるいは等しいかを比較する回路をコンパレータと呼びます。以下は、2つの8ビットの入力a, bのどちらが大きいかを比較し、 aの方が大きければgt(Greater Than)、 bの方が大きければlt(Less Than)、 aとbが等しければeqが1となるコンパレータをVHDLで記述したものです。
library ieee;
use ieee.std_logic_1164.all;
entity cmp is
port ( a, b: in std_logic_vector(7 downto 0); gt, lt, eq: out std_logic; );
end cmp;
architecture arch of cmp is
begin
process (a, b) begin gt <= '0'; lt <= '0'; eq <= '0'; if (a > b) then gt <= '1'; elsif (a < b) then lt <= '1'; else eq <= '1'; end if end proess;
end arch;
この例では、まずgt, lt, eqを最初に0にしておき、その後、該当するもののみを1にする、という処理を書いてあります。この場合、プログラミング言語の場合は、gtなどの変数がまず0になり、その後1になるわけですが、VHDLで記述しているのは回路ですので、実際に、まずgtが0になったあとで1になる、ということは起こらず、結果として(この場合はプロセス文が終わった時点で)gtの値がどうなっているか、だけが意味を持つことに注意しておきましょう。
カウンタ
以下、ウェブで見つけた例。4bitのカウンタ。
Verilog-HDL ソースファイルの書式3(例)
module cnt (clk, clr, q);
input clk, clr;
output [3:0] q;
reg [3:0] q;
always @(posedge clk)
begin
if (!clr)
q <= 0;
else
q <= q + 1;
end
endmodule
[[Verilog-HDL ソースファイルの書式3(例)
module cnt (clk, clr, q);
input clk, clr;
output [3:0] q;
reg [3:0] q;
always @(posedge clk)
begin
if (!clr)
q <= 0;
else
q <= q + 1;
end
endmodule
カウンタとコンパレータで検索していたら、PWMの記事に当たった。なるほど、たしかに。
事例2.パルス波のデューティ比を変えて白色LEDの明るさを調整する回路
module pwm( pw, pout, clk, nreset );
parameter DIV=20 ; ←clkを分周してPWMの周波数を設定する分周比
input [7:0] pw ;←※1 output pout ; input clk ; input nreset ;
reg [7:0] cnt ; reg [15:0] div ; reg pout ;
always @( posedge clk or negedge nreset ) begin if( !nreset )begin←※2 pout <= 0 ; cnt <= 0 ; div <= 0 ; end
else begin div <= (div == DIV )? 0 : div + 1 ; ←clkの分周 cnt <= cnt + ( div == 0 ) ;←※3 pout <= (pw >= cnt );
end end
endmodule