記述例 - シリアル受信回路

[] [] []


RTL記述の感じをつかんでもらうために記述例をあげる。

■機能

シリアルデータ(クロック同期,8ビット固定長)をシフトレジスタで受信して、パラレルデータとして出力する。

全系はクロック(clk,100MHz)のみで動作させるため、遅いシリアルクロック(s_clk,10MHz)はサンプリングして立ち上がりエッジのパルス(s_clk_rise)を作り、このタイミングでシリアルイネーブルとデータをサンプリングする。

■ブロック図

■タイミングチャート

■Verilogによる記述例

/* serrcv.v - serial receive */

module serrcv

  (input rst  // リセット

  ,input s_clk // シリアルクロック

  ,input s_enb // シリアルイネーブル

  ,input s_dat // シリアルデータ

  ,input clk  // クロック

  ,output[7:0] p_dat // パラレルデータ

  );

reg [2:0] s_clk_r;   // s_clkのシフトレジスタ

wire      s_clk_rise; // s_clkの立ち上がりエッジ

reg       s_enb_r;    // s_enb入力レジスタ

reg [2:0] cnt_r;     // s_enb長カウンタ

reg [7:0] rcv_r;     // s_datのシフトレジスタ

reg [7:0] p_dat_r;   // p_dat出力レジスタ

 

/* s_clkのエッジを検出する */

always @(posedge clk or posedge rst) begin

  if(rst)

    s_clk_r[2:0] <= 3'd0;

  else

    s_clk_r[2:0] <= {s_clk_r[1:0],s_clk};

end

assign s_clk_rise = (s_clk_r[2:1]==2'b01);

 

/* s_enbをラッチする */

always @(posedge clk or posedge rst) begin

  if(rst)

    s_enb_r <= 1'b0;

  else if(s_clk_rise)

    s_enb_r <= s_enb;

end

 

/* s_datをシリアルパラレル変換する */

always @(posedge clk or posedge rst) begin

  if(rst)

    rcv_r[7:0] <= 8'd0;

  else if(s_clk_rise)

    rcv_r[7:0] <= {rcv_r[6:0],s_dat};

end

 

/* s_enbの長さをカウントする*/

always @(posedge clk or posedge rst) begin

  if(rst)

    cnt_r <= 3'd0;

  else if(s_clk_rise)

    cnt_r <= (s_enb_r)? (cnt_r + 1'b1):3'd0;

end

 

/* 8ビット入力したらパラレルレジスタに入れる */

always @(posedge clk or posedge rst) begin

  if(rst)

    p_dat_r <= 3'd0;

  else if(s_clk_rise & (cnt_r==3'd7))

    p_dat_r <= rcv_r;

end

 

endmodule


[] [] []