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

[] [] []


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_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出力レジスタ

 

/* 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


[] [] []