●指令(プロンプト)

FPGAデザインを作ってください

## Application
カラーLEDをカラフルに点灯させてください.
グラデーションで7色に変化させます

## FPGA Board
MAX10-FB

## FPGA
10M08SAE144C8G

## I/O
Clock | Pin_27
LED RED | Pin_120
LED BLUE | Pin_121
LED GREEN | Pin_122
SW_n | Pin_123

●応答

このままで動けば、RGB LED はゆっくり 赤→橙→黄→緑→水→青→紫→赤 と変化します。
ただし、実ボードの RGB LED が 負論理だった場合は発光が逆になります。

そのときは rgb_rainbow_max10.v の先頭パラメータを、

parameter         LED_ACTIVE_LOW = 1'b1

クロックだけは要確認です

まず rgb_rainbow_max10.v のここです。

今の構成は 50 MHz 想定です。
もし MAX10-FB 基板の Pin_27 が別周波数なら、次の2か所を同じ値にそろえてください。

parameter integer CLK_HZ = 50_000_000

次に max10_fb_rgb7.sdc のここです。

create_clock -name clk -period 20.000 [get_ports {clk}]

●Verilogコード トップモジュール(rgb_rainbow_max10.v)

Verilog
module rgb_rainbow_max10 #(
    parameter integer CLK_HZ        = 50_000_000, // 実クロックに合わせて変更
    parameter integer FADE_STEP_HZ  = 200,        // 色更新レート
    parameter         LED_ACTIVE_LOW = 1'b0       // LEDが負論理なら 1'b1
)(
    input  wire clk,        // Pin_27
    input  wire sw_n,       // Pin_123 (active low)
    output wire led_red,    // Pin_120
    output wire led_blue,   // Pin_121
    output wire led_green   // Pin_122
);

    localparam integer TICK_DIV = CLK_HZ / FADE_STEP_HZ;

    //============================================================
    // SW同期化
    //============================================================
    reg sw_ff0 = 1'b1;
    reg sw_ff1 = 1'b1;

    always @(posedge clk) begin
        sw_ff0 <= sw_n;
        sw_ff1 <= sw_ff0;
    end

    wire sw_n_sync = sw_ff1;

    //============================================================
    // PWM生成用カウンタ
    //============================================================
    reg [7:0] pwm_cnt = 8'd0;

    always @(posedge clk) begin
        pwm_cnt <= pwm_cnt + 8'd1;
    end

    //============================================================
    // 色変化タイミング生成
    //============================================================
    reg [31:0] tick_cnt = 32'd0;
    reg [2:0]  phase    = 3'd0;   // 0..6
    reg [7:0]  step     = 8'd0;   // 0..255

    always @(posedge clk) begin
        if (!sw_n_sync) begin
            tick_cnt <= 32'd0;
            phase    <= 3'd0;
            step     <= 8'd0;
        end
        else begin
            if (tick_cnt == TICK_DIV - 1) begin
                tick_cnt <= 32'd0;

                if (step == 8'hFF) begin
                    step <= 8'd0;
                    if (phase == 3'd6)
                        phase <= 3'd0;
                    else
                        phase <= phase + 3'd1;
                end
                else begin
                    step <= step + 8'd1;
                end
            end
            else begin
                tick_cnt <= tick_cnt + 32'd1;
            end
        end
    end

    //============================================================
    // 7色グラデーション生成
    // 0: 赤     -> 橙
    // 1: 橙     -> 黄
    // 2: 黄     -> 緑
    // 3: 緑     -> 水
    // 4: 水     -> 青
    // 5: 青     -> 紫
    // 6: 紫     -> 赤
    //============================================================
    reg [7:0] r_val;
    reg [7:0] g_val;
    reg [7:0] b_val;

    wire [7:0] half_step = {1'b0, step[7:1]}; // 0..127

    always @* begin
        case (phase)
            3'd0: begin
                // red(255,0,0) -> orange(255,127,0)
                r_val = 8'hFF;
                g_val = half_step;
                b_val = 8'h00;
            end

            3'd1: begin
                // orange(255,127,0) -> yellow(255,255,0)
                r_val = 8'hFF;
                g_val = 8'd127 + half_step;
                b_val = 8'h00;
            end

            3'd2: begin
                // yellow(255,255,0) -> green(0,255,0)
                r_val = 8'hFF - step;
                g_val = 8'hFF;
                b_val = 8'h00;
            end

            3'd3: begin
                // green(0,255,0) -> cyan(0,255,255)
                r_val = 8'h00;
                g_val = 8'hFF;
                b_val = step;
            end

            3'd4: begin
                // cyan(0,255,255) -> blue(0,0,255)
                r_val = 8'h00;
                g_val = 8'hFF - step;
                b_val = 8'hFF;
            end

            3'd5: begin
                // blue(0,0,255) -> violet(127,0,255)
                r_val = half_step;
                g_val = 8'h00;
                b_val = 8'hFF;
            end

            3'd6: begin
                // violet(127,0,255) -> red(255,0,0)
                r_val = 8'd127 + half_step;
                g_val = 8'h00;
                b_val = 8'hFF - step;
            end

            default: begin
                r_val = 8'hFF;
                g_val = 8'h00;
                b_val = 8'h00;
            end
        endcase
    end

    //============================================================
    // PWM比較
    //============================================================
    wire r_pwm = (r_val == 8'hFF) ? 1'b1 : (pwm_cnt < r_val);
    wire g_pwm = (g_val == 8'hFF) ? 1'b1 : (pwm_cnt < g_val);
    wire b_pwm = (b_val == 8'hFF) ? 1'b1 : (pwm_cnt < b_val);

    //============================================================
    // LED極性対応
    //============================================================
    assign led_red   = (LED_ACTIVE_LOW) ? ~r_pwm : r_pwm;
    assign led_green = (LED_ACTIVE_LOW) ? ~g_pwm : g_pwm;
    assign led_blue  = (LED_ACTIVE_LOW) ? ~b_pwm : b_pwm;

endmodule

●ピンレイアウト(rgb_rainbow_max10.qsf)

set_global_assignment -name FAMILY "MAX 10"
set_global_assignment -name DEVICE 10M08SAE144C8G
set_global_assignment -name TOP_LEVEL_ENTITY rgb_rainbow_max10
set_global_assignment -name VERILOG_FILE rgb_rainbow_max10.v

set_location_assignment PIN_27  -to clk
set_location_assignment PIN_120 -to led_red
set_location_assignment PIN_121 -to led_blue
set_location_assignment PIN_122 -to led_green
set_location_assignment PIN_123 -to sw_n

set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led_red
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led_blue
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led_green
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to sw_n

●タイミング制約(rgb_rainbow_max10.sdc)

create_clock -name clk -period 20.000 [get_ports {clk}]

●動いた

コメントを残す