2015-12-10 2 views
0

Я пытаюсь написать модуль для остановки секундомера BCD. когда я проверяю синтаксис, я получаю ошибки:Операторы Verilog if-else

ERROR:HDLCompilers:26 - "../counter.v" line 24 expecting 'end', found 'else' 
ERROR:HDLCompilers:26 - "../counter.v" line 25 unexpected token: '=' 
ERROR:HDLCompilers:26 - "../counter.v" line 25 unexpected token: '+' 
ERROR:HDLCompilers:26 - "../counter.v" line 25 expecting 'endmodule', found '1' 

в середине моего кода. Я не совсем уверен, откуда исходит ошибка, и попытался реализовать больше begin/end, но это не лишило проблемы. Вот мой код в настоящее время:

module BCDCount(en, clk, rst, direction, cTenths, cSec, cTS, cMin); 
    input en, clk, rst, direction; 
    output [3:0] cTenths, cSec, cTS, cMin; 
    reg [3:0] cTenths, cSec, cTS, cMin; 

always @(posedge clk) 
if(en) 
begin 

    if(direction == 0) 

     if(cMin== 4'b 1001) 
       cMin <= 4'b 0000; 
      if(cTS == 4'b 0101) 
       cTS <= 4'b 0000; 
       cMin = cMin +1; 

       if(cSec == 4'b 1001) 
        cSec <= 4'b 0000; 
        cTS = cTS +1; 
        if(cTenths == 4'b 1001) 
         cTenths <= 4'b 0000; 
         cSec = cSec+1; 
        else 
         cTenths = cTenths +1; 
       else 
        cSec = cSec+1; 
      else 
       cTS = cTS + 1; 

    if(direction == 1) 

     if(cMin== 4'b 0000) 
      cMin <= 4'b 1001; 
      if(cTS == 4'b 0000) 
       cTS <= 4'b 1001; 
       cMin = cMin -1; 
       if(cSec == 4'b 0000) 
        cSec <= 4'b 1001; 
        cTS = cTS -1; 
         if(cTenths == 4'b 0000) 
          cTenths <= 4'b 1001; 
          cSec = cSec-1; 
         else 
          cTenths = cTenths -1; 
       else 
        cSec = cSec-1; 
      else 
       cTS = cTS - 1; 

end 
    always @(posedge rst) 
     begin 
      cMin <= 0; 
      cTS <= 0; 
      cSec <= 0; 
      cTenths <= 0; 
     end 
endmodule 
+0

Вам нужно начинать с конца каждого отдельного if-else. Ознакомьтесь с последним примером в этой ссылке: https://www.doulos.com/knowhow/verilog_designers_guide/if_statement/ – tanjir

ответ

1

на основе вашей структуры проминания, это выглядит, как вы ожидаете, что для этого кода

... 
     if(cTS == 4'b 0101) 
      cTS <= 4'b 0000; 
      cMin = cMin +1; 
       if(cTenths == 4'b 1001) 
    ... 

Cmin = cMin + 1 будет выполняться в том случае, cTS == 4'b0101. Однако в Verilog операторы if применимы только к оператору, непосредственно предшествующему им (как и в C). Чтобы они применимы к нескольким операторам, нам необходимо обернуть эти заявления в begin - end блоках (как и {} в C).

Итак, вы получаете ошибки в том, что ваш код имеет оператор else, но он не может найти подходящий if!

Вы хотите использовать следующее:

... 
     if(cTS == 4'b 0101) 
     begin 
      cTS <= 4'b 0000; 
      cMin = cMin +1; 
       if(cTenths == 4'b 1001) 
      ... 
     end 
     else 
    ... 

Edit: Также стоит отметить - вы смешиваете блокировки (=) и неблокирующая (<=) назначения в вашем always блоке. Для тактовых блоков always вы должны (в основном) всегда использовать неблокирующие назначения. Переместите любое последовательное назначение в свой собственный блок [email protected](*).

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

+1

SO также добавляет логику сброса в отдельный всегда блок, который является большим no-no для RTL. Он должен быть перемещен в один всегда блок: 'always @ (posedge clk, posedge rst) begin if (rst) begin/* reset code here */end else begin/* последовательный код здесь */end end' – Greg