FC2カウンター FPGAの部屋 キャラクタ描画テスト回路の経過1(エラー出まくり)
FC2ブログ

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

FPGAの部屋

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

キャラクタ描画テスト回路の経過1(エラー出まくり)

キャラクタ描画テスト回路を一応、Verilogコーディングし終えて、デバックをしているがエラー出まくり。
現在のProject Navigatorの様子を下に示す。こんな感じの階層になっている。
Char_Draw_Test_2_100203.png

今出来なくて悩んでいることがある。それはparameterでビット幅を定義することだ。defineでビット幅を定義できることは知っているのだけど、parameter ではできないのだろうか?

parameter DECODE_ADDRESS_LENGTH = 4; // デーコードするアドレス長、上のビットから何ビットデーコードするか。

parameter CHAR_GEN_CONTROLLER_ADDR = DECODE_ADDRESS_LENGTH'hF; // キャラクタ生成コントローラのアドレスマップ
parameter DDR2_SDRAM_ADDR = DECODE_ADDRESS_LENGTH'h0;

cpu_address <= {CHAR_GEN_CONTROLLER_ADDR, (DECODE_ADDRESS_LENGTH-8)'d4, 4'd0};
cpu_address <= {CHAR_GEN_CONTROLLER_ADDR, (32-(DECODE_ADDRESS_LENGTH+4))'d4, 4'd0};


上の例がエラーになってしまう。どうやって書くかを検索中。

(たっくさんの最初のコメント後に修正)
上に書き写したVerilogソースが間違っていたので修正しました。すみません。
つまり、DECODE_ADDRESS_LENGTH, CHAR_GEN_CONTROLLER_ADDR, DDR2_SDRAM_ADDRのパラメータを別のインクルードファイルにしておいて、お手軽にすべてのVerilogソースのアドレスデコードのビット幅を変化させたいということです。やってみたのですが、DECODE_ADDRESS_LENGTH'hFとかは書けないみたいです。つまりビット幅の所にパラメータで定義した値を書けないのかな?ということです。
これだと上の3行のシンタックスチェックが通るのはやってあります。(cpu_address = ... は確かめていない)

`define DCODE_ADDRESS_LENGTH 4 // デーコードするアドレス長、上のビットから何ビットデーコードするか。

parameter CHAR_GEN_CONTROLLER_ADDR = `DECODE_ADDRESS_LENGTH'hF; // キャラクタ生成コントローラのアドレスマップ
parameter DDR2_SDRAM_ADDR = `DECODE_ADDRESS_LENGTH'h0;

cpu_address <= {CHAR_GEN_CONTROLLER_ADDR, (32-(`DECODE_ADDRESS_LENGTH+4))'d4, 4'd0};


#今度は大丈夫かな?心配になってきた。。。

(2010/02/04追記)
上の最後の行はエラーになると、たっくさんに教えていただいた。たっくさん、ありがとうございました。
結局、このように書き直した。

parameter DECODE_ADDRESS_LENGTH = 4; // デーコードするアドレス長、上のビットから何ビットデーコードするか。

parameter CHAR_GEN_CONTROLLER_ADDR = 4'hF; // キャラクタ生成コントローラのアドレスマップ
parameter DDR2_SDRAM_ADDR = 4'h0;

cpu_address[31:31-(DECODE_ADDRESS_LENGTH-1)] <= CHAR_GEN_CONTROLLER_ADDR;
cpu_address[31-(DECODE_ADDRESS_LENGTH):4] <= 4;
cpu_address[3:0] <= 4'd0;


ついでに、アドレスマップを定義するAddress_Map_Define.vhを下に示す。

// Address_Map_Define.vh
// アドレスマップを定義する

    parameter DECODE_ADDRESS_LENGTH = 4; // デーコードするアドレス長、上のビットから何ビットデーコードするか。
    
    parameter CHAR_GEN_CONTROLLER_ADDR = 4'hF; // キャラクタ生成コントローラのアドレスマップ
    parameter DDR2_SDRAM_ADDR = 4'h0;


次に、キャラクタ生成コントローラのコマンド、ステータスレジスタのマップを表すCommand_Status_Define.vhを示す。

// Command_Status_Define.vh

    // Command Registers
    
    // 0番地の割り当て
    parameter CHAR_CODE_UPPER_HIGH        = 31; // キャラクタ・コードの上位バイト
    parameter CHAR_CODE_UPPER_LOW        = 24;
    parameter CHAR_CODE_LOWER_HIGH        = 23; // キャラクタ・コードの下位バイト
    parameter CHAR_CODE_LOWER_LOW        = 16;
    parameter NOT_PAINTED_BACKGROUND    = 15; // 0 - 文字の背景を塗りつぶす, 1 - 文字の背景を塗りつぶさない
    parameter DRAW_IMMEDIATELY            = 14; // 0 - 8番地の書き込みを待つ, 1 - 0番地の書き込みだけで描画
    parameter RED_FEILD_HIGH            = 11;
    parameter RED_FEILD_LOW                = 8;
    parameter GREEN_FEILD_HIGH            = 7;
    parameter GREEN_FEILD_LOW            = 4;
    parameter BLUE_FEILD_HIGH            = 3;
    parameter BLUE_FEILD_LOW            = 0;
    
    // 4番地の割り当て
    parameter MAGNIFICATION_HIGH        = 15; // 拡大倍率
    parameter MAGNIFICATION_LOW            = 11;
    // Red, Green, Blue の割り当ては0番地と同じ
    
    // 8番地の割り当て
    parameter VRAM_START_ADDRESS_HIGH    = 31;
    parameter VRAM_START_ADDRESS_LOW    = 0;
    
    // Status Register
    parameter FIFO_COUNT_HIGH            = 4;
    parameter FIFO_COUNT_LOW            = 0;
    
    // 各領域のビット幅
    `define CHAR_CODE_UPPER_WIDTH 8
    `define CHAR_CODE_LOWER_WIDTH 8
    `define RED_FEILD_WIDTH 4
    parameter RED_FEILD_WIDTH = 4;
    `define GREEN_FEILD_WIDTH 4
    parameter GREEN_FEILD_WIDTH = 4;
    `define BLUE_FEILD_WIDTH 4
    parameter BLUE_FEILD_WIDTH = 4;
    `define MAGNIFICATION_WIDTH 5
    `define VRAM_START_ADDRESS_WIDTH 32
    `define FIFO_COUNT_WIDTH 5


最後に、今回問題のあった記述のあるプロセッサの代わりをするステートマシン、Char_Draw_for_Test.v

// テスト用キャラクタ描画モジュール
// Char_Draw_for_Test.v
// 
// グラフィックメモリの先頭からキャラクタを描画する。0~9まで、A~Zまで描画したら元に戻る。背景色は黒とする
// Char_Gen_Controller.v のCPUのインターフェースを操作する。
// DDR2 SDRAMは64Mbytes, よって先頭を0x0とすると0x3FF_FFFFまで。
// グラフィックメモリは1024X768X2bytes = 1,572,864 bytes = 0x18_0000
// グラフィックメモリは0x300_0000からとする
// キャラクタは128X96文字 = 12,288文字を1画面に描画できる

`default_nettype none

module Char_Draw_for_Test (clk_vga, reset_vga, cpu_address, cpu_write_data, cpu_read_data, cpu_data_we);

    input wire clk_vga; // VGAのクロック、65MHzの予定
    input wire reset_vga; // clk_vga用リセット
    output reg [31:0] cpu_address; // CPUのアドレス
    output wire [31:0] cpu_write_data; // CPUのWrite データ
    input wire [31:0] cpu_read_data; // CPUのRead データ
    output reg cpu_data_we; // CPUのデータ入力のWrite Enable
    
    `include "Address_Map_Define.vh"
    `include "Command_Status_Define.vh"
    
    parameter idle_char                = 6'b000001;
    parameter CGC_first_cmd0_set    = 6'b000010;
    parameter CGC_cmd4_set            = 6'b000100;
    parameter CGC_cmd8_set            = 6'b001000;
    parameter Wait_CGC_cmd0            = 6'b010000;
    parameter CGC_cmd0_loop            = 6'b100000;
    reg [5:0] cs_char;
    reg [7:0] char_code_count; // キャラクタのカウンタ
    reg [RED_FEILD_HIGH:RED_FEILD_LOW] red_count;
    reg [GREEN_FEILD_HIGH:GREEN_FEILD_LOW] green_count;
    reg [BLUE_FEILD_HIGH:BLUE_FEILD_LOW] blue_count;
    wire op_ena;
    reg [13:0] vram_disp_count;
    reg [31:0] cmd_data;

    // 周波数分周
    freqdiv #(.DIVISOR(3250000)) // 65MHzを20Hzにする
    freqdiv_inst (
        .clk(clk_vga),
        .reset(reset_vga),
        .op_ena(op_ena)
    );
    
    // キャラクタを書きまくるステートマシン
    always @(posedge clk_vga) begin
        if (reset_vga)
            cs_char <= idle_char;
        else begin
            case (cs_char)
                idle_char :
                    cs_char <= CGC_first_cmd0_set;
                CGC_first_cmd0_set : // キャラクタ生成コントローラの0番地に最初のキャラクタと色をセット
                    cs_char <= CGC_cmd4_set;
                CGC_cmd4_set : // キャラクタ生成コントローラの4番地背景色、倍率をセット
                    cs_char <= CGC_cmd8_set;
                CGC_cmd8_set : // キャラクタ生成コントローラの8番地アドレスをセットして1キャラクタ描画
                    cs_char <= Wait_CGC_cmd0;
                Wait_CGC_cmd0 : // 次のキャラクタを書くまでのWait
                    if ((cpu_read_data[FIFO_COUNT_HIGH:FIFO_COUNT_LOW]<5'h01110) && op_ena)
                        cs_char <= CGC_cmd0_loop;
                CGC_cmd0_loop : // ループしながらキャラクタと色を+1しながら
                    if (vram_disp_count>14'd12287) // 1画面描画済み
                        cs_char <= CGC_first_cmd0_set;
                    else
                        cs_char <= Wait_CGC_cmd0;
            endcase
        end
    end
    
    
    // キャラクタ生成コントローラのコマンドデータの用意
    always @(posedge clk_vga) begin
        if (reset_vga) begin
            cpu_address <= 32'd0;
            cmd_data <= 32'd0;
            cpu_data_we <= 1'b0;
        end else begin
            case (cs_char)
                idle_char :begin
                    cpu_address <= 32'd0;
                    cmd_data <= 32'd0;
                    cpu_data_we <= 1'b0;
                end
                CGC_first_cmd0_set : begin
                    cpu_address[31:31-(DECODE_ADDRESS_LENGTH-1)] <= CHAR_GEN_CONTROLLER_ADDR;
                    cpu_address[31-(DECODE_ADDRESS_LENGTH):4] <= 0;
                    cpu_address[3:0] <= 4'd0;
                    
                    cmd_data[CHAR_CODE_UPPER_HIGH:CHAR_CODE_UPPER_LOW] <= 0;
                    cmd_data[CHAR_CODE_LOWER_HIGH:CHAR_CODE_LOWER_LOW] <= `CHAR_CODE_LOWER_WIDTH'h30; // 0x30
                    cmd_data[NOT_PAINTED_BACKGROUND] <= 1'b0; // 背景を塗りつぶす
                    cmd_data[DRAW_IMMEDIATELY] <= 1'b0; // アドレスの書き込みを待つ
                    cmd_data[DRAW_IMMEDIATELY-1 : RED_FEILD_HIGH+1] <= 0;
                    cmd_data[RED_FEILD_HIGH:RED_FEILD_LOW] <= red_count;
                    cmd_data[GREEN_FEILD_HIGH:GREEN_FEILD_LOW] <= green_count;
                    cmd_data[BLUE_FEILD_HIGH:BLUE_FEILD_LOW] <= blue_count;
                    
                    cpu_data_we <= 1'b1;
                end
                CGC_cmd4_set : begin
                    cpu_address[31:31-(DECODE_ADDRESS_LENGTH-1)] <= CHAR_GEN_CONTROLLER_ADDR;
                    cpu_address[31-(DECODE_ADDRESS_LENGTH):4] <= 0;
                    cpu_address[3:0] <= 4'd4;
                    
                    cmd_data[31:MAGNIFICATION_HIGH+1] <= 0;
                    cmd_data[MAGNIFICATION_HIGH:MAGNIFICATION_LOW] <= 0; // 倍率1倍
                    cmd_data[RED_FEILD_HIGH:RED_FEILD_LOW] <= `RED_FEILD_WIDTH'd0;
                    cmd_data[GREEN_FEILD_HIGH:GREEN_FEILD_LOW] <= `GREEN_FEILD_WIDTH'd0;
                    cmd_data[BLUE_FEILD_HIGH:BLUE_FEILD_LOW] <= `BLUE_FEILD_WIDTH'd0;
                    
                    cpu_data_we <= 1'b1;
                end
                CGC_cmd8_set : begin
                    cpu_address[31:31-(DECODE_ADDRESS_LENGTH-1)] <= CHAR_GEN_CONTROLLER_ADDR;
                    cpu_address[31-(DECODE_ADDRESS_LENGTH):4] <= 0;
                    cpu_address[3:0] <= 4'd8;
                    
                    cmd_data <= VRAM_START_ADDRESS;
                    cpu_data_we <= 1'b1;
                end
                Wait_CGC_cmd0 : begin
                    cpu_address[31:31-(DECODE_ADDRESS_LENGTH-1)] <= CHAR_GEN_CONTROLLER_ADDR;
                    cpu_address[31-(DECODE_ADDRESS_LENGTH):4] <= 0;
                    cpu_address[3:0] <= 4'd0;
                    
                    cmd_data[CHAR_CODE_UPPER_HIGH:CHAR_CODE_UPPER_LOW] <= 0;
                    cmd_data[CHAR_CODE_LOWER_HIGH:CHAR_CODE_LOWER_LOW] <= char_code_count;
                    cmd_data[NOT_PAINTED_BACKGROUND] <= 1'b0; // 背景を塗りつぶす
                    cmd_data[DRAW_IMMEDIATELY] <= 1'b1; // アドレスの書き込みを待つ
                    cmd_data[DRAW_IMMEDIATELY-1 : RED_FEILD_HIGH+1] <= 0;
                    cmd_data[RED_FEILD_HIGH:RED_FEILD_LOW] <= red_count;
                    cmd_data[GREEN_FEILD_HIGH:GREEN_FEILD_LOW] <= green_count;
                    cmd_data[BLUE_FEILD_HIGH:BLUE_FEILD_LOW] <= blue_count;
                    
                    cpu_data_we <= 1'b0;
                end
                CGC_cmd0_loop : begin
                    cpu_address[31:31-(DECODE_ADDRESS_LENGTH-1)] <= CHAR_GEN_CONTROLLER_ADDR;
                    cpu_address[31-(DECODE_ADDRESS_LENGTH):4] <= 0;
                    cpu_address[3:0] <= 4'd0;
                    
                    cmd_data[CHAR_CODE_UPPER_HIGH:CHAR_CODE_UPPER_LOW] <= 0;
                    cmd_data[CHAR_CODE_LOWER_HIGH:CHAR_CODE_LOWER_LOW] <= char_code_count;
                    cmd_data[NOT_PAINTED_BACKGROUND] <= 1'b0; // 背景を塗りつぶす
                    cmd_data[DRAW_IMMEDIATELY] <= 1'b1; // アドレスの書き込みを待つ
                    cmd_data[DRAW_IMMEDIATELY-1 : RED_FEILD_HIGH+1] <= 0;
                    cmd_data[RED_FEILD_HIGH:RED_FEILD_LOW] <= red_count;
                    cmd_data[GREEN_FEILD_HIGH:GREEN_FEILD_LOW] <= green_count;
                    cmd_data[BLUE_FEILD_HIGH:BLUE_FEILD_LOW] <= blue_count;
                    
                    cpu_data_we <= 1'b1;
                end
            endcase
        end
    end
    assign cpu_write_data = cmd_data;
    
    // vram_disp_count の処理
    always @(posedge clk_vga) begin
        if (reset_vga)
            vram_disp_count <= 14'd0;
        else
            if (cs_char==CGC_cmd8_set || cs_char==CGC_cmd0_loop) begin
                if (vram_disp_count>14'd12287)
                    vram_disp_count <= 14'd0;
                else
                    vram_disp_count <= vram_disp_count + 14'd0;
            end
    end
            
    // キャラクタのカウンタ
    always @(posedge clk_vga) begin
        if (reset_vga)
            char_code_count <= 8'h30;
        else begin
            if (cs_char==CGC_cmd8_set || cs_char==CGC_cmd0_loop) begin
                if (char_code_count==8'h39) // 9
                    char_code_count <= 8'h41; // A
                else if (char_code_count==8'h5A) // Z
                    char_code_count <= 8'h61; // a
                else if (char_code_count==8'h7A) // z
                    char_code_count <= 8'h30; // 0
                else
                    char_code_count <= char_code_count + 8'd1;
            end
        end
    end
    
    // Red のカウント
    always @(posedge clk_vga) begin
        if (reset_vga)
            red_count <= {RED_FEILD_WIDTH{1'b1}};
        else
            if (cs_char==CGC_cmd8_set || cs_char==CGC_cmd0_loop)
                red_count <= red_count - `RED_FEILD_WIDTH'd1;
    end
    
    // Green のカウント
    always @(posedge clk_vga) begin
        if (reset_vga)
            green_count <= {GREEN_FEILD_WIDTH{1'b1}};
        else
            if ((cs_char==CGC_cmd8_set || cs_char==CGC_cmd0_loop) && red_count==`RED_FEILD_WIDTH'd0) // Redが0の時に-1
                green_count <= green_count - `GREEN_FEILD_WIDTH'd1;
    end
    
    // Blue のカウント
    always @(posedge clk_vga) begin
        if (reset_vga)
            blue_count <= {BLUE_FEILD_WIDTH{1'b1}};
        else
            if ((cs_char==CGC_cmd8_set || cs_char==CGC_cmd0_loop) && green_count==`GREEN_FEILD_WIDTH'd0) // Greenが0の時に-1
                blue_count <= blue_count - `BLUE_FEILD_WIDTH'd1;
    end
    
endmodule


なお、まだシミュレーションしていないので、変更する可能性があります。(というか、絶対に変更になるでしょう?)

(2010/02/05:追記)
上のChar_Draw_for_Test.vを書き換えました。ブロック文とノンブロック文が混在していました。どうもRubyを書いていてVerilogを書くと混在になってしまいます。。。

(2010/02/07:追記)
Command_Status_Define.vhの各領域のビット幅を下のように修正しました。

// 各領域のビット幅
`define CHAR_CODE_UPPER_WIDTH 8
`define CHAR_CODE_LOWER_WIDTH 8
`define RED_FEILD_WIDTH 4
`define GREEN_FEILD_WIDTH 4
`define BLUE_FEILD_WIDTH 4
`define MAGNIFICATION_WIDTH 5
`define VRAM_START_ADDRESS_WIDTH 32
`define FIFO_COUNT_WIDTH 5
parameter RED_FEILD_WIDTH = `RED_FEILD_WIDTH;
parameter GREEN_FEILD_WIDTH = `GREEN_FEILD_WIDTH;
parameter BLUE_FEILD_WIDTH = `BLUE_FEILD_WIDTH;


  1. 2010年02月03日 06:14 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:11

コメント

いつも御世話になっています。

この記述のビット幅の意図を分かっていないのですが、例えば次のように書きます。

parameter DECODE_ADDRESS_LENGTH = 4;
parameter [DECODE_ADDRESS_LENGTH-1:0] CHAR_GEN_CONTROLLER_ADDR = {DECODE_ADDRESS_LENGTH {1'b1}}; //連接内で使用しているのでビット幅を明示します
parameter DDR2_SDRAM_ADDR = {DECODE_ADDRESS_LENGTH{4'b1111}};
reg [DECODE_ADDRESS_LENGTH+DECODE_ADDRESS_LENGTH*3+4-1:0] cpu_address;

initial begin
cpu_address <= {CHAR_GEN_CONTROLLER_ADDR, {(DECODE_ADDRESS_LENGTH){3'b100}}, 4'd0};
end

連接のリピートは、{repeat{expr,expr,...}}です。repeat項は、1以上の定数である必要があります。(例えば、DECODE_ADDRESS_LENGTH -8) だとマイナスになってしまいます)
連接内のビット幅は、明示しないと駄目なので、パラメータもビット幅を明示しました。
  1. 2010/02/03(水) 07:56:05 |
  2. URL |
  3. たっく #-
  4. [ 編集 ]

たっくさん、こんにちは。

早速のお返事ありがとうございます。本文を変えてしまって申し訳ありません。
本文に書いたように、ビット幅のところにparameter で宣言した値を使いたいと思っています。やはりdefineするのが一番良いでしょうか?
  1. 2010/02/03(水) 08:58:43 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

>>DECODE_ADDRESS_LENGTH'hFとかは書けないみたいです。
はい、言語仕様(レキサレベル)で、ありません。単に4'hf とかしか書けません。

ですから、
cpu_address <= {CHAR_GEN_CONTROLLER_ADDR, (32-(`DECODE_ADDRESS_LENGTH+4))'d4, 4'd0};
は、処理系でエラーを吐く筈です。マクロは、単なる文字列の置きかえですので、defineで書くのはつらいと思います。

2001だと下のような感じでどうでしょうか?

`define DECODE_ADDRESS_LENGTH 4 //

parameter CHAR_GEN_CONTROLLER_ADDR ={ `DECODE_ADDRESS_LENGTH {1'b1}}; // キャラクタ生成コントローラのアドレスマップ
parameter DDR2_SDRAM_ADDR = {`DECODE_ADDRESS_LENGTH {1'b0}};
parameter [32-(`DECODE_ADDRESS_LENGTH+4)-1:0] D4='d4;
reg [`DECODE_ADDRESS_LENGTH+32-(`DECODE_ADDRESS_LENGTH+4)+4-1:0] cpu_address;


initial cpu_address <= {CHAR_GEN_CONTROLLER_ADDR, D4, 4'd0};

cpu_address宣言は、単に32ビット固定でいいのかもしれない、と気づきましたが、concatから推論した、ビット幅依存の例ということで。

  1. 2010/02/03(水) 13:44:35 |
  2. URL |
  3. たっく #-
  4. [ 編集 ]

後は、使用しているところで、下のようにすればよいと思います。

module xx;

`include "marsees_parameter_file.h"

~記述
endmodule

SVだと$bitsというビット幅を求める便利が演算子があったり、pkgでプロジェクトのリテラル関連をまとめることができるので、これより少しスマートに書けますが、2001だと、多分上のような感じだと思います。
  1. 2010/02/03(水) 13:57:15 |
  2. URL |
  3. たっく #-
  4. [ 編集 ]

parameterでビット幅を定義・・・

こんにちは、ネットサーフィンをしててこのページにたどり着きました。
parameterでビット幅を定義・・・ですが、以下のようにもできますよね。

parameter DAW = 4; // DECODE_ADDRESS_LENGTH
parameter CGCW = 4; // CHAR_GEN_CONTROLLER_ADDR_LENGTH
parameter DAV = 'h4; // DECODE_ADDRESS_VALUE
parameter CGCA = 'hF; // CHAR_GEN_CONTROLLER_ADDR
parameter PAV = {(32-(CGCW+DAW+4)){1'b0}}; // PADDING VALUE

....

cpu_address <= {CGCA[CGCW-1:0], PAV, DAV[DAW-1:0], 4'd0};


  1. 2010/02/06(土) 16:00:45 |
  2. URL |
  3. suna #-
  4. [ 編集 ]

sunaさん、こんにちは。
こういうふうにも書けるんですね。勉強になりました。ありがとうございました。書き直してみます。
  1. 2010/02/06(土) 18:44:03 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

sunaさん、教えていただいた方法で書き直してみたのですが、
green_count <= green_count - 'd1[GREEN_FEILD_WIDTH-1:0];
が論理合成を通らないので元に戻します。
  1. 2010/02/06(土) 20:05:47 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

こんばんは、sunaです。 (^_^)

文法規則では、数値(number)は[msb:lsb]形式で記述できないことになっているので、
green_count <= green_count - 'd1[GREEN_FEILD_WIDTH-1:0];
のような記述はダメです。
その場合は、
parameter ONE = 'd1;
とでも定義しておいて、
green_count <= green_count - ONE[GREEN_FEILD_WIDTH-1:0];
と記述するとか。。でしょうね。
でも、単純に1減算するだけのカウンタなら私なら、
green_count <= green_count - 1'b1;
と書いちゃいますね。

あと、if文の記述ですが、begin,endが殆ど付いていませんが気持ち悪くないですか?
if文がネストしていて、
if ...
if ...
else ...
みたいな構造の場合にelseがどっちのifに対するものなのかわからなくなるので、
私は必ずbegin 〜 endで括るようにしてます。

  1. 2010/02/06(土) 21:53:44 |
  2. URL |
  3. suna #-
  4. [ 編集 ]

sunaさん、度々ありがとうございました。
>green_count <= green_count - 'd1[GREEN_FEILD_WIDTH-1:0];
>のような記述はダメです。
了解しました。

やはり、どうもわかりやすく書けそうにないので、今のままで行くことにしましたが、defineを先に定義して、parameterの値はdefineの値を使うことにしました。

>green_count <= green_count - 1'b1;
ですが、Verilogのビット幅拡張はどのように作用するのでしょうか?green_countと同じ幅に1'b1を拡張してくれますか?
この辺りでは、以前痛い目にあったことがあって慎重になっています。
http://marsee101.blog19.fc2.com/blog-entry-763.html

>あと、if文の記述ですが、begin,endが殆ど付いていませんが気持>ち悪くないですか?
仕事では、VHDLで書いているので、必ずend if; を書いているので、Verilogではなるべく省略していますが、
if begin
 if
end else
とかは、ちゃんとbegin ~ end を書いていると思います。
  1. 2010/02/07(日) 04:30:50 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

了解しました。
そもそも、こちらのページを見て、ビット幅定義をパラメトリックにする方法について
こういう方法もあるよなぁ〜っと考えてたら、つい、commentを書いてしまいました。
こうすべきだとか、ああすべきだとか、を主張する意図はまったくありません。

> ですが、Verilogのビット幅拡張はどのように作用するのでしょうか?green_countと同じ幅に1'b1を拡張してくれますか?
> この辺りでは、以前痛い目にあったことがあって慎重になっています。
> http://marsee101.blog19.fc2.com/blog-entry-763.html

手元に、 IEEE Std 1364-2001 IEEE STANDARD VERILOG® があるんですが、
これ(p60. Table29-Bit lengths resulting from self-determind expressions)によると、
"i + j"の式の場合は結果はmax(L(i),L(j))となっていますので、
green_count - 1'b1
の結果はgreen_countの幅になる筈です。
これを、green_countに代入するわけですから問題ないと思いますが。

また、同じTable29にはUnsized constant numberのbit幅はsame as integerとなっていますので、
> http://marsee101.blog19.fc2.com/blog-entry-763.html
に書いてあるケースのrp-1は1がunsized constant numberですので、32bit幅と解釈され、
上記のmax(L(i),L(j))の規則でrp-1の結果は32bitになってしまうんじゃないかと思います。
rpの値が0の場合はrp-1の結果は32'hFFFFFFFFになりますのでwpと一致することはなくなりますよね。

marseeさんのケースの場合は、
wire [x:0] full_th; // full閾値 ... rpと同じbit幅
assign full_th = rp - 1;
として、
assign fifo_full = (full_th==wp) ? 1'b1: 1'b0;
とすればよかったかも知れませんね。

では、頑張ってくださいね。 (^_^)/~~

追伸
YahooのFPGAの部屋に登録しました。
機会があればまた。
  1. 2010/02/07(日) 20:50:18 |
  2. URL |
  3. suna #-
  4. [ 編集 ]

sunaさん、こんにちは。
いろいろ教えていただいて、ありがとうございます。こんな書き方もあるのか?と勉強になりました。また、コメントをお願いいたします。
YahooのFPGAの部屋に登録していただいて、ありがとうございました。また、よろしくお願いいたします。

max(L(i),L(j))の規則によると、rpよりも小さいビット幅のリテラルだったら大丈夫ですね。
  1. 2010/02/07(日) 21:08:26 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

コメントの投稿


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

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