Моделирование ModelSim работает, но FPGA не работает. Что мне не хватает? - PullRequest
1 голос
/ 19 апреля 2020

Извините, если что-то здесь кажется очевидным, но я начинаю с этой новой FPGA, и мне очень нравится это, но это сводит меня с ума. Вот код Verilog для блока, который в принципе должен выполнять следующие действия с 8-битным регистром:

00000001

00000010

00000100

.. ...

01000000

10000000

01000000

00100000

module bit_bouncer(clock, enable, bouncer_out);
//INPUTS PORTS
input clock;
input enable;
//OUTPUTS PORTS
output bouncer_out;
//INPUT DATA TYPE
wire clock;
wire enable;
//OUTPUT DATA TYPE
reg [7:0] bouncer_out = 8'b00000001;
//Register to store data
reg direction = 0;

//CODE STARTS HERE
always @ (posedge clock) begin
    if(enable) begin
        bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
        direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
    end
end

endmodule

Отлично работает в симуляции, но не работает на ПЛИС (Доска DE10-Nano, если интересно). Я также должен отметить, что это вызывается синхронизацией, прошедшей через PLL на FPGA, которая затем передается через блок DivByN. Вот код для блока DivByN:

module clk_divn #(
parameter WIDTH = 20,
parameter N = 1000000)

(clk,reset, clk_out);

input clk;
input reset;
output clk_out;

reg [WIDTH-1:0] pos_count = {WIDTH{1'b0}};
reg [WIDTH-1:0] neg_count = {WIDTH{1'b0}};
wire [WIDTH-1:0] r_nxt = {WIDTH{1'b0}};

 always @(posedge clk)
 if (reset)
 pos_count <=0;
 else if (pos_count ==N-1) pos_count <= 0;
 else pos_count<= pos_count +1;

 always @(negedge clk)
 if (reset)
 neg_count <=0;
 else  if (neg_count ==N-1) neg_count <= 0;
 else neg_count<= neg_count +1; 

assign clk_out = ((pos_count > (N>>1)) | (neg_count > (N>>1))); 
endmodule

DivBYN также был протестирован в симуляции и работает нормально. Я фактически сделал симуляцию, в которой divByN подключен к «bouncer_block», если я могу так его назвать, и это тоже работает.

Все моделирует, но в реальной жизни ничего не работает .... но не работает это всегда так: P

Я надеюсь, что кто-то может помочь мне понять это, потому что я действительно хочу узнать больше о FPGA и использовать их в будущих проектах.

Если вы прочитаете все это, вы офигенно, и я sh тебе замечательный день :) 1029 *

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Я попытался добавить сброс безуспешно, но я сделал свой собственный DivByN и сохранил сброс, предложенный Чарльзом, и теперь он работает безупречно. Я думаю, что код для DivByN, который я взял в Интернете, может быть не в состоянии синтезировать должным образом. Вот мой новый код для divByN:

module my_div_n #(parameter N = 1_000_000, parameter WIDTH = 20) (clock_in, 

clock_out);
input wire clock_in;
output reg clock_out;
reg[WIDTH-2:0] counter; //WIDTH-2 because the last bit is taken care of by the fact that we flip the output (it acts as the last bit)

always @ (posedge clock_in) begin
    counter <= counter + 19'b1;
    if(counter == N>>1) begin
        counter <= 0;
        clock_out <= !clock_out;
    end
end

endmodule

И код для моего bit_bouncer:

module bit_bouncer(clock, enable, reset, bouncer_out);
//INPUTS PORTS
input clock;
input enable;
input reset;
//OUTPUTS PORTS
output [7:0] bouncer_out;
//INPUT DATA TYPE
wire clock;
wire enable;
wire reset;
//OUTPUT DATA TYPE
reg [7:0] bouncer_out;
//Register to store data
reg direction;

//CODE STARTS HERE
always @ (posedge clock) begin
    if(reset) begin
        bouncer_out <= 8'b00000001;
        direction <= 0;
    end
    else if(enable) begin
        bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
        direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
    end
end

endmodule

Вот как все подключено:

The circuit block diagram

Я все еще хотел бы знать назначение тактового импульса, потому что у вас создается впечатление, что я, вероятно, должен знать это, если я хочу лучше понять свою схему и все о синхронности.

0 голосов
/ 19 апреля 2020

Ваш разрядник не работает синхронно с системными часами и не имеет условия сброса, что является причиной неполадок.

Лучшим подходом является использование тактового строба и проверка его на края основных системных часов. Кроме того, все входные сигналы от тактильных кнопок должны быть синхронизированы с системными часами и деблокированы. Примерно так:

Схемы c

enter image description here

RTL

enter image description here

BitBouncer

module BitBouncer
(
    input wire clock,
    input wire reset,
    input wire enable,
    input wire clock_strobe,
    output reg[7:0] bouncer_out
);

    // Register to store data
    reg direction = 0;

    // CODE STARTS HERE
    always @(posedge clock)
    begin
        if (reset)
        begin
            bouncer_out = 1;
            direction = 0;
        end
        else if (enable && clock_strobe)
        begin
            bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
            direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
        end
    end

endmodule

ClockStrobe

module ClockStrobe
#(
    parameter MAX_COUNT = 50000000
)
(
    input wire clock,
    input wire reset, 
    output reg clock_strobe
);

    reg [$clog2(MAX_COUNT) - 1: 0] counter;

    always @(posedge clock)
    begin
        if (reset)
        begin
            counter <= 0;
        end
        else
        begin
            counter <= counter + 1;
            if (counter == MAX_COUNT)
            begin
                clock_strobe <= 1;
                counter <= 0;
            end
            else
            begin
                clock_strobe <= 0;
            end
        end
    end

endmodule

Syn c

module Sync
(
    input wire clock,
    input wire in,
    output reg out
);

    reg [2:0] sync_buffer;

    initial
    begin
        out = 0;
        sync_buffer = 3'd0;
    end

    always @*
    begin
        out <= sync_buffer[2];
    end

    always @(posedge clock)
    begin
        sync_buffer[0] <= in;
        sync_buffer[2:1] <= sync_buffer[1:0];
    end

endmodule

Debounce

module Debounce
#(
    parameter MAX_COUNT = 2500000
)
(
    input wire clock,
    input wire in,
    output reg out
);

    reg previous_in;

    reg [$clog2(MAX_COUNT) - 1:0] counter;

    initial begin
        previous_in = 0;
        counter = 0;
        out = 0;
    end

    always @(posedge clock)
    begin
        counter <= counter + 1;
        if (counter == MAX_COUNT)
        begin
            out <= previous_in;
            counter <= 0;
        end
        else if (in != previous_in)
        begin
            counter <= 0;
        end
        previous_in <= in;
    end

endmodule
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...