とりあえず、Timer1モジュールのデバッグは終了。CCPモジュールがらみの部分があるが、これはまたあとで。
プリスケーラの制御ではまりまくって、何度か書き直しが必要だった。
Timer1モジュールの非同期モードはとりあえず、実装しないことにしたが、2つのクロックの間で正しく、データのやり取りができるモジュールを考えてみた(ソースコードは最後)。簡単にデバッグもして、問題なく動作しているようだが、スループットがあまりよいとはいえないな・・・
----
本日の御託
家内に「おっぱっぴ~」だと、言われた。なんかへこむ。
「でもそんなのかんけいねぇ!」(笑)
1 //
2 // common clock domain cross module
3 // (c)2007 BakaOyaji
4
5 module common_cdc(
6 input src_clk_i,
7 input src_por_i,
8 input src_ready_i,
9 output src_ack_o,
10
11 input dst_clk_i,
12 input dst_por_i,
13 input dst_ready_i,
14 output dst_we_o
15 ) ;
16
17 parameter SRC_IDLE = 2'b00, SRC_WAITFOR1 = 2'b01 , SRC_WAITFOR0 = 2'b10;
18 parameter DST_IDLE = 2'b00, DST_WAITFOR_READY = 2'b01,
19 DST_WAITFOR0 = 2'b10 ;
20
21 reg [1:0] src_fsm , dst_fsm ;
22 reg [1:0] s2d, d2s ; // synchronizer to remove meta-stability
23 wire a_s2d, a_d2s ; // asynchronous signals between 2 clock domains
24 wire s_s2d, s_d2s ; // synchronous version
25
26 // FSM in source side
27 always@( posedge src_clk_i) begin
28 if( src_por_i ) begin
29 d2s <= 2'b0 ;
30 src_fsm <= SRC_IDLE ;
31 end // if
32 else begin
33 d2s <= { d2s[0], a_d2s } ;
34 (* parallel_case *)
35 casex( src_fsm )
36 SRC_IDLE : begin
37 if( src_ready_i ) begin
38 src_fsm <= SRC_WAITFOR1 ; // start fsm
39 end
40 // else stay
41 end
42 SRC_WAITFOR1 : begin
43 if( s_d2s ) begin
44 src_fsm <= SRC_WAITFOR0 ;
45 end
46 // else stay
47 end
48 SRC_WAITFOR0 : begin
49 if( ~s_d2s ) begin
50 if( src_ready_i ) begin
51 src_fsm <= SRC_WAITFOR1 ; // start fsm Short cut!
52 end // if
53 else begin
54 src_fsm <= SRC_IDLE ;
55 end // if
56 end // else
57 // else stay
58 end
59 default :
60 src_fsm <= SRC_IDLE ;
61 endcase
62 end // else
63 end // always
64 assign a_s2d = (src_fsm == SRC_WAITFOR1 ) ? 1'b1 : 1'b0 ;
65 assign src_ack_o = ( src_fsm == SRC_WAITFOR1) ? d2s[1] : 1'b0 ;
66 assign s_d2s = d2s[1] ; // for debug use only
67