2016-09-15 2 views
0

`Timescale 1ns/1psVerilog поведенческий код получения моделируется правильно, но не работает, как ожидалось на FPGA

module StateMachine(
    input [1:0] OP, 
    input [1:0] RESULT_COM, 
    input clk, 
    input rst, 
    output reg [1:0] CONTROL_AS=0, 
    output reg RESET_C, 
    output reg CONTROL_C, 
    output reg [1:0] state=0 
    ); 

    parameter toLOWER=2'b01,toUPPER=2'b10,IDLE=0; 
    reg [1:0] n_state = IDLE; 
    //reg [1:0] state = IDLE; 
    reg [1:0] p_state = IDLE; 
    reg [1:0] prevOP = 2'b00; 
    reg [1:0] p_state_copy = 2'b00; 
    reg [15:0] count = 0; 

    always @ (posedge clk) 
    begin 
    if(rst == 1) 
     RESET_C = 1; 
    else 
     RESET_C = 0; 

     if(OP == 2'b01) 
     n_state = toLOWER; 
     else 
     if(OP == 2'b10) 
     n_state = toUPPER; 
     else 
     n_state = IDLE; 

     if(prevOP == OP) 
     p_state = state; 

     if((OP != prevOP && OP[0] != OP[1]) || (rst == 1 && (OP != 2'b00 && OP != 2'b11))) 
     CONTROL_C = 1; 
     else 
     CONTROL_C = 0; 

     if(state != n_state)  
     prevOP = OP; 

     state = n_state; 
    end 

    always @ (n_state) 
    begin 
     p_state_copy = p_state;  
    end 

    always @ (p_state) 
    begin 
     case(p_state) 
     toLOWER: 
     begin 
      if(RESULT_COM == 2'b10) 
      CONTROL_AS <= 2'b10; 
      else 
      CONTROL_AS <= 2'b00; 
     end 

     toUPPER: 
     begin 
      if(RESULT_COM == 2'b01) 
      CONTROL_AS <= 2'b01; 
      else 
      CONTROL_AS <= 2'b00; 
     end 

     IDLE: 
     begin 
      if(p_state_copy == toUPPER && RESULT_COM == 2'b01) 
       CONTROL_AS <= 2'b01; 
      else if(p_state_copy == toLOWER && RESULT_COM == 2'b10) 
       CONTROL_AS <= 2'b10; 
      else if(p_state_copy == toUPPER && RESULT_COM == 2'b10) 
       CONTROL_AS <= 2'b0; 
      else if(p_state_copy == toLOWER && RESULT_COM == 2'b01) 
       CONTROL_AS <= 2'b0; 
      else if(p_state_copy == toUPPER && RESULT_COM == 2'b0) 
       CONTROL_AS <= 2'b0; 
      //(p_state_copy == toLOWER && RESULT_COM == 2'b0) 
      else CONTROL_AS <= 2'b0; 
     end 

     endcase 
    end 
endmodule  

Это письмо конвертер. OP - 2 бита. 11 и 00 означает ничего не делать. 01 загрузите следующую букву из ПЗУ (используя счетчик для обновления адреса) и конвертируйте в нижний регистр. 10 загрузите следующую букву и преобразуйте ее в нижний регистр. письмо не будет преобразовано, если оно не в верхнем или нижнем регистре, либо в нижнем регистре, но OP хочет преобразовать его в нижний регистр и т. д. Если входные данные (00 или 11) или действительный вход не были всегда подтверждены (01 или 10) , то вывод остается.

Я использую p_state_copy, чтобы сохранить предыдущее состояние, и когда наступает следующий передний фронт clk, он частично перекрывается с состоянием. Таким образом, он может проверить, является ли предыдущее состояние IDDLE (ввод 00 или 11). RESULT_COM - результат компаратора, который используется для проверки состояния букв. На картинке скрытая часть в РЕЗУЛЬТАТЕ равна 0, так как сбрасывается. enter image description here

Я могу имитировать, синтезировать и внедрять его. Но я не могу запустить его на доске. Могу я узнать, в чем проблема? Спасибо.

ответ

0
always @ (n_state) 
begin 
    p_state_copy = p_state;  
end 

Эта логика не может быть синтезирована. Нет никакого практического способа, чтобы FPGA защелкнула значение (например, p_state_copy) на смену логического сигнала (например, n_state).

Вообще говоря, always блоки кода, предназначенные для синтеза на FPGA должны быть чувствительны к любой posedge clk (или какой-либо другой тактового сигнала) для синхронных блоков, или * для случайной логики. Указание отдельных сигналов приведет вас к неприятностям.

0

В этом коде есть несколько вещей, которые не позволяют синтезировать его правильно.

always @ (posedge clk) 
begin 
    if(rst == 1) 
    RESET_C = 1; 

должно быть больше как

always @ (posedge clk or posedge rst) 
if(rst == 1) 
    RESET_C = 1; 
else 
begin 

Есть несколько всегда @ (...) списки чувствительности, которые являются неполными. например

always @ (p_state) 
begin 
    case(p_state) 
    toLOWER: 

отсутствует p_state_copy и RESULT_COM, которые я обнаружил до сих пор. Я бы предложил для ремонтопригодности использовать всегда @ (*) или даже лучше, если ваши инструменты позволяют always_comb

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

Вы также используете неблокирующие назначения в гребенчатом логическом блоке и блокируете назначения в блоке логики гребенки.

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

Далее, (первый == 1 & & (OP! = 2'b00 & & OP! = 2'b11)) Не будет синтезировать правильно. Вам нужно придерживаться стандартного шаблона Verilog с флип-флопом, если вы хотите, чтобы он правильно себя вел.

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

Смежные вопросы