Yuri Panchul (panchul) wrote,
Yuri Panchul
panchul

Что накупить для вводных FPGA лаб для студентов

Господа! Как вы знаете, я по субботам помогаю Тимуру Палташеву из AMD учить студентов в небольшом частном университете во Фримонте. Причина, почему я это делаю: так как я даю советы нашему менеджменту в Imagination Technologies по поводу образовательных программ в России, то я должен знать, как выглядит студент и что он понимает. Т.е. потренироваться на индусах и китайцах, а потом высказываться по поводу России. Кроме элементарных упражнений там будет и нечто продвинутое, о чем я расскажу через некоторое время.

Так вот. В текущий момент есть тактическая задача надрессировать студентов, чтобы они соединили FPGA плату с каким-нибудь устройтвом типа джойстика, температурного сенсора, дальномерки и т.д. Простые протоколы - SPI, I2C, UART. Конечные автоматы, основы кодирования на Verilog на уровне Register Transfer Level (RTL).

По этому поводу я делаю шоппинг и прошу вас оценить мой выбор. Обращаю внимание, что речь идет о простых хардверных (не софтверных) дизайнах. Например устройства с большим количеством регистров или сложной процедурой инициализации не покатит - к ним хорошо писать программу для микроконтроллера, но не плисовый хардвер.

Ниже:

1. Список для шоппинга с моими пометками, прошу комментировать

2. Мой код примерчега для цифрового потенциометра, чтобы вы оценили требуемый уровень сложности (элементарный)

3. Фотографии цифрового потенциометра, чтобы вы оценили пример




Крупно: список для шоппинга с моими пометками, прошу комментировать:

e1Screenshot 2015-02-26 21

e2Screenshot 2015-02-26 21

e3Screenshot 2015-02-26 21

e4Screenshot 2015-02-26 21

e5Screenshot 2015-02-26 21

e6Screenshot 2015-02-26 21

s7Screenshot 2015-02-26 21

e8Screenshot 2015-02-26 21.44.20 copy

s9Screenshot 2015-02-26 21

s99Screenshot 2015-02-26 21





Мой код примерчега для цифрового потенциометра и платы Digilent Cmod S6, чтобы вы оценили требуемый уровень сложности (элементарный):

Файл spi_transmitter.v


module spi_transmitter
(
    input            clock,
    input            reset,

    input      [7:0] data,

    input            transmit,
    output reg       ready,

    output reg       sclk,
    output reg       sdi,
    output reg       cs
);

    localparam IDLE                = 0,
               DRIVE_POSEDGE_CLOCK = 1,
               DRIVE_DATA          = 2;

    reg       d_ready;
    reg       d_sclk;
    reg       d_sdi;
    reg       d_cs;

    reg [2:0] counter;
    reg [6:0] shift_reg;
    reg [1:0] state;

    reg [2:0] d_counter;
    reg [6:0] d_shift_reg;
    reg [1:0] d_state;

    always @*
    begin
        d_ready     = ready;
        d_sclk      = 0;
        d_sdi       = sdi;
        d_cs        = cs;

        d_counter   = counter;
        d_shift_reg = shift_reg;
        d_state     = state;
        
        case (state)

        IDLE:
        begin
            if (transmit)
            begin
                d_ready     = 0;
                d_sclk      = 0;
                d_sdi       = data [7];
                d_cs        = 0;

                d_counter   = 7;
                d_shift_reg = data [6:0];
                
                d_state     = DRIVE_POSEDGE_CLOCK;
            end
            else
            begin
                d_cs        = 1;
            end
        end

        DRIVE_POSEDGE_CLOCK:
        begin
            d_sclk    = 1;
            // d_sdi stays the same

            if (d_counter == 0)
            begin
                d_ready = 1;
                d_state = IDLE;
            end
            else
            begin
                d_state = DRIVE_DATA;
            end
        end

        DRIVE_DATA:
        begin
            d_sclk      = 0;
            d_sdi       = d_shift_reg [6];

            d_counter   = d_counter - 3'd1;
            d_shift_reg = d_shift_reg << 1;

            d_state     = DRIVE_POSEDGE_CLOCK;
        end
		  
        endcase
    end

    always @(posedge clock)
    begin
        if (reset)
        begin
            ready     <= 1;
            sclk      <= 0;
            sdi       <= 0;
            cs        <= 0;

            counter   <= 0;
            shift_reg <= 0;
            state     <= IDLE;
        end
        else
        begin
            ready     <= d_ready;
            sclk      <= d_sclk;
            sdi       <= d_sdi;
            cs        <= d_cs;
                                      
            counter   <= d_counter;
            shift_reg <= d_shift_reg;
            state     <= d_state;
        end
    end

endmodule

//--------------------------------------------------------------------

module cmod_s6_pmod_dpot
(
    input        clock,

    input  [1:0] buttons,
    output [3:0] leds,

    output       dpot_vcc,
    output       dpot_gnd,
    output       dpot_sclk,
    output       dpot_sdi,
    output       dpot_cs
);

    wire reset    = buttons [0];
    wire increase = buttons [1];

    assign dpot_vcc = 1'b1;
    assign dpot_gnd = 1'b0;

    reg [7:0] d_resistance;
    reg       d_transmit;

    reg [7:0] resistance;
    reg       transmit;

    wire      ready;

    spi_transmitter spi_transmitter_inst
    (
        .clock     ( clock       ),
        .reset     ( reset       ),

        .data      ( resistance  ),

        .transmit  ( transmit    ),
        .ready     ( ready       ),

        .sclk      ( dpot_sclk   ),
        .sdi       ( dpot_sdi    ),
        .cs        ( dpot_cs     )
    );

    always @*
    begin
        d_resistance = resistance;
        d_transmit   = 0;

        if (ready & increase)
        begin
            d_resistance = d_resistance + 19;
            d_transmit   = 1;
        end
    end

    always @(posedge clock)
    begin
        if (reset)
        begin
            resistance <= 0;
            transmit   <= 0;
        end
        else
        begin
            resistance <= d_resistance;
            transmit   <= d_transmit;
        end
    end

    assign leds [0] = clock;
    assign leds [1] = dpot_sclk;
    assign leds [2] = dpot_sdi;
    assign leds [3] = ready;

endmodule

//--------------------------------------------------------------------

Файл spi_transmitter.ucf для обозначения соединений

NET "clock" LOC = "N7" | IOSTANDARD = LVCMOS33;

NET "buttons<0>" LOC = "P8" | IOSTANDARD = LVCMOS33;
NET "buttons<1>" LOC = "P9" | IOSTANDARD = LVCMOS33;

NET "leds<0>" LOC = "N3" | IOSTANDARD = LVCMOS33;
NET "leds<1>" LOC = "P3" | IOSTANDARD = LVCMOS33;
NET "leds<2>" LOC = "N4" | IOSTANDARD = LVCMOS33;
NET "leds<3>" LOC = "P4" | IOSTANDARD = LVCMOS33;

NET "dpot_vcc"  LOC = "K1" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "dpot_gnd"  LOC = "K2" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "dpot_sclk" LOC = "L1" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "dpot_sdi"  LOC = "M1" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "dpot_cs"   LOC = "M2" | IOSTANDARD = LVCMOS33 | PULLUP;






С сайта Digilent:



Моя фотка:

2015-02-21 11.13.34



Что вы одобряете из моего списка для вводных лаб для студентов? (Напомню, интерфейс к FPGA, а не микроконтроллеру)?

Датчик прикосновения
5(7.4%)
Цифровой потенциометр
4(5.9%)
UART для подключения к PC через USB
5(7.4%)
16x2 алфавитно-цифровой дисплей с интерфейсами SPI, I2C и UART
7(10.3%)
Простая 16-кнопочная клавиатура
5(7.4%)
Джойстик с интерфейсом SPI
5(7.4%)
Rotary encoder - как это по русски - ну хрень, которая поворачивается
6(8.8%)
Модуль с 4 кнопочками для дополнительной отладки
3(4.4%)
Модуль с LED - удобно для отладки SPI или UART -соединения
5(7.4%)
Дальномерка (pulse-width или UART интерфейсы)
8(11.8%)
Сенсор света с SPI
7(10.3%)
Сенсор температуры с I2C
5(7.4%)
Я предлагаю иное (написать в комментариях)
3(4.4%)
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 51 comments