GOWIN RUMBERのLチカを階層に分割してみる

前回のGOWIN RUMBERのLチカは階層なしですべてをトップ階層に置くという乱暴なものでした。

これをTOP階層とCLK生成、LED信号生成に分けてみました。

まず、TOP階層(top.v)

/* デバイスは GW1N-4B(GW1N-UV4LQ144C6/I5) */ 

module top
  (
    input wire CLK_IN,
    input wire RST_N,
    input wire SW,
    output wire [2:0] RGB_LED,
    output wire [7:0] LED
  );

  wire SYSCLK;
  wire SLWCLK;

  clk clk1(
    .RST_N(RST_N),
    .CLK_G(CLK_IN),
    .INTCLK(SYSCLK),
    .SLWCLK(SLWCLK)
);

  wire SW1;
  reg SSW1;	// 同期化したSW1
  wire [2:0] RGBLED1 ;
  reg dir;
  reg [3:0] dsw ;
	
  led led1(
    .RST_N(RST_N),
    .SYSCLK(SYSCLK),
    .DIR(dir),
    .RGB_LED(RGBLED1)
  );
	
  // SWのチャタリング除去
  always @(posedge SLWCLK)begin
    if(RST_N==0)begin
      dsw = 4'b1;
    end
    else begin
      dsw[3:1] <= dsw[2:0];
      dsw[0]   <= SW1;
    end
  end

  always @(posedge SLWCLK)begin
    if( dsw == 4'b1100 ) begin
       SSW1 <= 1;
    end
    else begin 
       SSW1 <= 0;
    end
  end

  always @(posedge SLWCLK)begin
    if(SSW1 == 1)begin
      dir <= dir ? 1'b0 : 1'b1 ;
    end
    else begin
      dir <= dir ;
    end
  end

  assign RGB_LED = RGBLED1;
  assign SW1 = SW;

  assign LED[0] = dir;
  assign LED[1] = SW1;
  assign LED[7:2] = 6'b0000000;

endmodule

次にクロック生成(clk.v)

module clk(
	input wire RST_N,
	input wire CLK_G,
	output wire INTCLK,
    output wire SLWCLK
);


reg [4:0] ckci;     // 1MHz生成用カウンタ
reg cki;			
	
reg [16:0] ckcs;     // 100Hz生成用カウンタ
reg cks;			
	
// 1MHz周期のクロック信号生成
// 12MHzクロックをカウントして1MHzのクロックを作る。
// 立ち上がりエッジしか使わないからデューティはどうでもよいので、
// 12MHzの1周期幅(=83ns)幅とする。
// 
// _____|~|________|~|________|~|________
// 
// 同様に12MHzクロックをカウントして100Hzのクロックを作る。
// (チャタリング防止用)
//
always @(posedge CLK_G)begin
	if(RST_N==0)begin
		ckci = 1'b1;
	end
	if(ckci == 5'd11)
	begin
		ckci <= 5'b0 ;
		cki <= 1'b1;
	end
	else begin
		ckci <= ckci + 1'b1;
		cki <= 1'b0;
	end
end

assign INTCLK = cki;

always @(posedge CLK_G)begin
	if(RST_N==0)begin
		ckcs = 1'b1;
	end
	if(ckcs == 17'd119999)
	begin
		ckcs <= 17'b0 ;
		cks <= 1'b1;
	end
	else begin
		ckcs <= ckcs + 1'b1;
		cks <= 1'b0;
	end
end

assign SLWCLK = cks;

endmodule

LED信号生成(led.v)

module led
(
input wire RST_N,
input wire SYSCLK,
input wire DIR,
output wire [2:0] RGB_LED
);

parameter time1 =    10'd1000 - 1'd1;
// parameter time2 = 10'd1000 - 1'd1; // 1秒周期
parameter time2 = 10'd500 - 1'd1; // 0.5秒周期

reg [2:0] rled;
reg [2:0] rledout;
reg [9:0] count1;   // PWM DUTY用(1ms周期)
reg [9:0] count2;   // PWM レベル用(1s周期)

reg [9:0] duty;

wire dir;

assign dir = DIR;

initial
begin
  count1=10'b0;
  count2=10'b0;
  rled <= 3'b110;
end

always @(posedge SYSCLK)begin
    if(RST_N==0)begin
        count1 <= 10'b0;
        count2 <= 10'b0;
        rled <= 3'b110;
    end

    begin
        if(count1 == time1)
        begin 
            count1<= 10'd0;
        end
        else begin
            count1 <= count1 + 1'b1;
        end
    end

    // count1の1周期で0〜999(time2)までカウント
    if(count1 == time1)
        begin
            if(count2 == time2)
            begin 
                count2<= 10'd0;
                rled <= dir ? {rled[1:0],rled[2]} : {rled[0],rled[2:1]} ;
            end
            else
                count2 <= count2 + 1'b1;
        end

    // LEDを駆動するPWM信号生成
    begin
        if(count2 < time2/2)
            duty = count2 * 2;
        else 
            duty = (time2 - count2) * 2;

        if(count1 < duty)
            rledout = rled;
        else
            rledout = 3'b111;

    end
end

assign RGB_LED[0] = rledout[0];
assign RGB_LED[1] = rledout[1];
assign RGB_LED[2] = rledout[2];

endmodule

初回の論理合成と端子の割付は前回と同様に実施しました。

今回はGowin Analyzer Oscilloscopeで内部信号をモニタしてみます。Designerでファイルの新規作成で「GAO Config File」を作成します。作成したら、作成したraoファイルをダブルクリックしてRTLで信号選択するのかNetListで信号選択するのかといったことや、対象信号、対象クロックを設定します。(Gowin Analyzer Oscilloscopeを使うのは2回目なので、前回ほど詳しく書きません)

設定したらファイルを保存して、論理合成・配置配線をし直します。

生成したら、Toolメニューの下かアイコンでGowin Analyzer Oscilloscopeを起動します。
(起動する前あたりで sudo modprobe -r ftdi_sio を実行しておきます)

Enable Programmerにチェックを入れます。

プログラマと同じ操作でDeviceやダウンロードするFsファイルを指定して、Enableにチェックを入れた後、プログラムします。

書き込みのプログレスバーが動かないのが気持ち悪いですが、動作が始まります。

Ready to acquire の右の再生ボタンをクリックするとキャプチャが始まり、メモリが埋まると無事に表示されました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)