Код Verilog моделирует, но не работает так, как прогнозируется на FPGA.

StackOverflow https://stackoverflow.com/questions/2435444

Вопрос

Я смоделировал поведение своего кода, и он работает отлично.Результаты соответствуют прогнозам.Когда я синтезирую свой код, загружаю его в спартанскую 3e FPGA и пытаюсь проанализировать с помощью чипскопа, результаты даже близко не соответствуют тем, которые я ожидал.Что я сделал неправильно?http://pastebin.com/XWMekL7r

Это было полезно?

Решение

Ваша проблема в строках 13-16, где вы задаете начальные значения для госрегистров:

 reg    [OUTPUT_WIDTH-1:0] previousstate = 0;              
 reg    [OUTPUT_WIDTH-1:0] presentstate = 1;
 reg    [6:0] fib_number_cnt = 1;  
 reg    [OUTPUT_WIDTH-1:0] nextstate = 1; 

Это эквивалент написания «начального» оператора, присваивающего эти значения, который не поддается синтезу — в аппаратном обеспечении не существует такого понятия, как значение по умолчанию.Когда вы помещаете свой проект в FPGA, все эти регистры будут принимать случайные значения.

Вместо этого вам необходимо инициализировать эти счетчики/состояния внутри вашего блока Always, когда значение сброса высокое.

always @(posedge clk or posedge reset)
  if (reset) begin
     previousstate <= 0;
     presentstate <= 1;
     ... etc ...
  end

Ответ на уточняющие вопросы:

Когда вы инициализируете такой код, в аппаратном обеспечении вообще ничего не происходит — он полностью игнорируется, как если бы вы ввели оператор $display.Инструмент синтеза пропускает все конструкции, предназначенные только для моделирования, обычно выдавая об этом какое-то предупреждение (это действительно зависит от инструмента).

Теперь вопрос о блокировке и неблокировке требует очень длинного ответа :).Я направлю вас к статье SNUG-2000, которая, вероятно, является лучшей статьей, когда-либо написанной по этой теме.Он отвечает на ваш вопрос, а также на многие другие по этой теме.Впоследствии вы поймете, почему использование операторов блокировки в последовательной логике считается плохой практикой и почему ваш код в любом случае отлично работает с операторами блокировки.

http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf


Еще ответы:

Обычный «шаблон» создания логики, подобной вашей, состоит в том, чтобы иметь два блока Always: один определяет логику, а другой определяет флопы.В первом случае вы используете операторы блокировки для реализации логики, а во втором — фиксируете (или сбрасываете) сгенерированное значение.Итак, что-то вроде этого:

wire some_input;

// Main logic (use blocking statements)
reg state, next_state;
always @*
  if (reset) next_state = 1'b0;
  else begin
    // your state logic
    if (state) next_state = some_input;
    else next_state = 1'b0;
  end

// Flops (use non-blocking)
always @(posedge clock)
  if (reset) state <= 1'b0;
  else state <= next_state;

Обратите внимание, что я использую синхронный сброс, но при необходимости вы можете использовать асинхронный.

Другие советы

Строки 13-16 верны."Рег [6: 0] fib_number_cnt = 1;" это не то же самое, что использование «начального» оператора.Прочтите руководство по синтезу Xilinx для более подробного описания инициализации регистров.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top