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

[] [] []


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

■機能

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

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

■ブロック図

■タイミングチャート

■Verilogによる記述例

/* serrcv.v - serial receive */

module serrcv

  (input rst_n  // リセット

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

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

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

  ,input clk    // クロック

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

  );

 

reg [2:0] s_clk_reg;    // s_clkのエッジ検出用シフトレジスタ

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

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

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

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

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

 

assign rst = ~rst_n;    // 内部リセットを正論理にする

 

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

always @(posedge clk or posedge rst)

  begin

  if(rst)

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

  else

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

  end

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

 

/* s_enbをラッチする */

always @(posedge clk or posedge rst)

  begin

  if(rst)

    s_enb_reg <= 1'b0;

  else if(s_clk_rise)

    s_enb_reg <= s_enb;

  end

 

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

always @(posedge clk or posedge rst)

  begin

  if(rst)

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

  else if(s_clk_rise)

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

  end

 

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

always @(posedge clk or posedge rst)

  begin

  if(rst)

    cnt_reg <= 3'd0;

  else if(s_clk_rise)

    cnt_reg <= (s_enb_reg)? (cnt_reg + 1'b1):3'd0;

  end

 

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

always @(posedge clk or posedge rst)

  begin

  if(rst)

    p_dat_reg <= 3'd0;

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

    p_dat_reg <= rcv_reg;

  end

 

endmodule


[] [] []