FC2カウンター FPGAの部屋 擬似乱数、M系列を使う2
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

擬似乱数、M系列を使う2

擬似乱数、M系列を使う1”の続き。

前回は8ビットのM系列を試してみたが、256回目で元のパターンに戻るので、ちょっと物足りないかな?と思ったので、16ビットのM系列の下8ビットを取ってみることにした。これならば、元のパターンに戻るのは、65536回目だ。

下に変更した下に、m_seq_test.v を示す。16ビットのM系列の下8ビットを取る mseq8_2 を増やした。

// M sequence test(m_seq_test.v)

`default_nettype none

module m_seq_test(
    input    wire         clk,
    input    wire        reset,
    output    reg [7:0]    mseq8,
    output    wire [7:0]    mseq8_2
);

    reg    [15:0]    mseq16;
    
    function [7:0] mseqf8_0 (input [7:0] din);
        reg xor_result;
        begin
            xor_result = din[7] ^ din[3] ^ din[2] ^ din[1];
            mseqf8_0 = {din[6:0], xor_result};
        end
    endfunction
    
    function [7:0] mseqf8_1 (input [7:0] din);
        reg xor_result;
        begin
            xor_result = din[7] ^ din[4] ^ din[2] ^ din[0];
            mseqf8_1 = {din[6:0], xor_result};
        end
    endfunction
    
    function [15:0] mseqf16 (input [15:0] din);
        reg xor_result;
        begin
            xor_result = din[15] ^ din[12] ^ din[10] ^ din[8] ^ din[7] ^ din[6] ^ din[3] ^ din[2];
            mseqf16 = {din[14:0], xor_result};
        end
    endfunction        
    
    always @(posedge clk) begin
        if (reset) 
            mseq8 <= 8'd1;
        else
            mseq8 <= mseqf8_0(mseq8);
    end
    
    always @(posedge clk) begin
        if (reset) 
            mseq16 <= 16'd1;
        else
            mseq16 <= mseqf16(mseq16);
    end
    assign mseq8_2 = mseq16[7:0];
    
endmodule

`default_nettype wire


16ビットのM系列のタップ位置は、95CC を選択した。15, 12, 10, 8, 7, 6, 3, 2ビット目のXOR をLSBに入れて左シフトしている。

m_seq_test.v をテストするm_seq_test_tb.v も変更した。下に示す。

`default_nettype none

`timescale 1ns / 1ps

module m_seq_test_tb;

    // Inputs
    reg clk = 1'b0;
    reg reset;
    wire [7:0] mseq8;
    wire [7:0] mseq8_2;

    // Instantiate the Unit Under Test (UUT)
    m_seq_test uut (
        .clk(clk), 
        .reset(reset), 
        .mseq8(mseq8),
        .mseq8_2(mseq8_2)
    );

    parameter        CLK_PERIOD = 10;
    parameter real    CLK_DUTY_CYCLE = 0.5;
    parameter        CLK_OFFSET = 0;
    parameter        START_STATE    = 1'b0;
    
    initial begin
        #CLK_OFFSET;
        forever begin
            clk = START_STATE;
            #(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk = ~START_STATE;
            #(CLK_PERIOD*CLK_DUTY_CYCLE);
        end
    end

    // リセットが解除された後から、mseq8の値をクロックが立ち上がるごとにmseq8.txtに書き込む
    integer F_HANDLE;
    initial F_HANDLE = $fopen("mseq8.txt");

    always @(posedge clk) begin
        if (~reset) begin
            $fdisplay(F_HANDLE, "%b", mseq8);
            $fflush(F_HANDLE);
        end
    end

    // リセットが解除された後から、mseq8_2の値をクロックが立ち上がるごとにmseq8_2.txtに書き込む
    integer F_HANDLE2;
    initial F_HANDLE2 = $fopen("mseq8_2.txt");

    always @(posedge clk) begin
        if (~reset) begin
            $fdisplay(F_HANDLE2, "%b", mseq8_2);
            $fflush(F_HANDLE2);
        end
    end

    initial begin
        // Initialize Inputs
        reset = 1'b1;

        // Wait 100 ns for global reset to finish
        #100;
        
        // Add stimulus here
        reset = 1'b0;
        
        #660000;
        $fclose(F_HANDLE);
        $fclose(F_HANDLE2);
        $finish;
    end
      
endmodule

`default_nettype wire



mseq8_2.txt の一部を下に示す。

00000001
00000010
00000100
00001001
00010011
00100110
01001101
10011011
00110110
01101100


65536回目から65545回目にかけても同じパターンがあった。

8ビットのM系列ではオール0はシードが無くなってしまうのでダメだったが、16ビットのM系列の下8ビットを使用するならばオール0も可能だ。よって、mseq16_f ファンクションの下位8ビットをAXI4バスのバースト長の設定値として使うことにする。

  1. 2012年03月28日 05:18 |
  2. IP
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/2096-2ad8ccea
この記事にトラックバックする(FC2ブログユーザー)