Код Verilog имитирует, но не работает так, как предсказано на FPGA - PullRequest
0 голосов
/ 12 марта 2010

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

Ответы [ 2 ]

5 голосов
/ 13 марта 2010

Ваша проблема со строками 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 @(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


Больше ответов:

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

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;

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

0 голосов
/ 08 апреля 2010

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

...