PSoCのUDB 7bitカウンターを使用する
Use a PSoC UDB 7bit counter
PSoCのプログラマブル論理回路は非常にタイトで、32bitレジスタを複数用意して制御しようとしただけでも許容値を超えてしまいます。そのようなリソース量を節約するための方法として、PSoC内蔵の7bitカウンタモジュールを使うというのがあります。
count7.v
cy_psoc3_count7 #(.cy_period(7'b111), .cy_route_ld(1), .cy_route_en(1))
DataCounter(
.clock(clock),
.reset(1'b0),
.load(count_reset),
.enable(1'b1),
.count(count),
.tc(data_tc)
);
cy_period | 周期。カウンターの値がこの値を上回ると、値はリセットされます。 |
cy_route_ld | loadパラメーターを使用するかどうか(1で使用) |
cy_route_en | enableパラメーターを使用するかどうか |
clock | カウンターを増やすために使用するクロック |
reset | カウンターのハードウェアをリセットする |
load | カウンターの値をリセットする。resetと違い、カウンター値以外に影響はしない |
enable | カウンターの有効状態。cy_route_enが0ならこの値は無視される |
count | ここで指定したレジスタに現在のカウンター値が格納される |
tc | カウンターが一巡した場合に、このレジスタに1が格納される |
カウンターを有効にするに当たり注意しておきたいのが、Verilog内だけではなくC言語(CPU)からも有効にさせる命令を実行させなければいけない点です(英語ドキュメントには具体例が言及されているのですが、
日本語ドキュメントでは抜け落ちています)。
カウンターを有効にするには「`$INSTANCE_NAME`_[関数で指定した名前]__CONTROL_AUX_CTL_REG」の6ビット目をHighにします。
api.h
#define `$INSTANCE_NAME`_enable() *((reg8*)`$INSTANCE_NAME`_DataCounter__CONTROL_AUX_CTL_REG) |= 0x20
このサンプルでは8カウント目に一巡するとdata_tc値がHighになるので、そのたびにLEDが明滅を繰り返します。また、ボタンとcount_resetは直結されており、ボタンを押している間は常にカウンター値がリセットされるため、その間は全く動いていないように見えます。
sample.v
`include "cypress.v"
module ctr (
output result,
input clock,
input count_reset
);
wire data_tc;
reg [6:0] count;
reg result_reg;
cy_psoc3_count7 #(.cy_period(7'b111),.cy_route_ld(1),.cy_route_en(1))
DataCounter(
.clock(clock),
.reset(1'b0),
.load(count_reset),
.enable(1'b1),
.count(count),
.tc(data_tc)
);
always @(posedge clock)
begin
if(data_tc)
begin
result_reg = ~result_reg;
end
end
assign result = result_reg;
endmodule
2019/06/28