2015-10-05 5 views
0
module accumulator (
    input [7:0] A , 
    input reset, 
    input clk, 
    output reg carryout, 
    output reg overflow, 
    output reg [8:0] S, 
    output reg HEX0, 
    output reg HEX1, 
    output reg HEX2, 
    output reg HEX3 
    ); 

    reg signA; 
    reg signS; 
    reg [7:0] magA; 
    reg [7:0] magS; 
    reg Alarger; 

    initial begin 
     S = 9'b000000000; 
    end 

    always_ff @ (posedge clk, posedge reset) begin 
     if (reset) begin 
      S = 9'b000000000; 
     end 
     else begin 

      begin 
      signA <= A[7];    //Is A negative or positive 
      signS <= S[7]; 
      S <= A + S; 
      end 

      if (signA == 1) begin   //A is negative so magnitude is of 2s compliment 
       magA <= (~A[7:0] + 1'b1); 
      end 
      else begin 
       magA <= A; 
      end 

      if (signS == 1) begin   //sum is negative so magnitude is of 2s compliment 
       magS <= (~S[7:0] + 1'b1); 
      end 
      else begin 
       magS <= S; 
      end 

      if (magA > magS) begin 
       Alarger <= 1'b1;  //Magnitude of A is larger than magnitude of sum 
      end 
      else begin 
       Alarger <= 1'b0; 
      end 

      if ((signA == 1) & (Alarger == 1) & (S[7] == 0)) begin 
       overflow <= 1'b1; 
      end 
      else begin 
       overflow <= 1'b0; 
      end 
      if ((signS == 1) & (Alarger == 0) & (S[7] == 0)) begin 
       overflow <= 1'b1; 
      end 
      else begin 
       overflow <= 1'b0; 
      end 
      if ((signS == 1) & (signA == 1) & (S[7] == 0)) begin 
       overflow <= 1'b1; 
      end 
      else begin 
       overflow <= 1'b0; 
      end 
      if ((signS == 0) & (signA == 0) & (S[7] == 1)) begin 
       overflow <= 1'b1; 
      end 
      else begin 
       overflow <= 1'b0; 
      end 
      if (S[8] == 1) begin   //carryout occurred 
       carryout <= 1'b1; 
       overflow <= 1'b0; 
       S <= 9'b000000000;  //sum no longer valid 
      end 
      else begin 
       carryout <= 1'b0; 
      end 

      display_hex h1     //display of A 
      (
       .bin   (magA), 
       .hexl   (HEX2), 
       .hexh   (HEX3) 
      ); 

      display_hex h2     //display of sum 
      (
       .bin   (S[7:0]), 
       .hexl   (HEX0), 
       .hexh   (HEX1) 
      ); 
     end 
    end 

endmodule 

Я пытаюсь сделать накопитель, который добавляет A (двоичное значение 8 цифр, которое может быть подписано или без знака) повторно к сумме. Когда сумма вычисляется, тогда сумма и A должны отображать значение на 4-х шести светодиодных индикаторах (2 светодиода для A и 2 светодиодов для суммы). Однако мне сложно скомпилировать его. Я искал код ошибки и, похоже, является общей ошибкой для синтаксической ошибки и может иметь несколько значений.Ошибка (10170): ожидается «<=» или «=» или «+ =» или «- =» или «* =» или «/ =» или «% =» или «& = ", или" | = ", или"^= "и т. д.

+1

Вы не должны определять подмодулях внутри 'always' блока. – Qiu

+0

Просто обратите внимание, что '-' выполняет двойное дополнение, то есть' ~ S [7: 0] + 1'b1 == -S [7: 0] ' – Morgan

ответ

0

я не был в состоянии воспроизвести точную ошибку, но перемещение инстанциацию display_hex вне always_ff решает главный вопрос:

module accumulator 
(
    /* ... */ 
); 
    // ... 

    always_ff @ (posedge clk, posedge reset) begin 
     /* ... */ 
    end 

    display_hex h1 (
     /* ... */ 
    ); 

    display_hex h2 (
     /* ... */ 
    ); 
endmodule 

Другое дело: Код гонит переменной S от initial, а также always. Это создает несколько драйверов, и код не будет компилироваться. Чтобы исправить это, полностью удалите исходный код, он вам не понадобится, так как S будет установлен в 0, если заявлено reset.

ИЛИ

Вы можете переместить всю логику в исходный блок; было бы выглядеть примерно так (но это, скорее всего, не будет синтезировать):

initial begin 
    S = 0; 

    forever begin 
     wait @(posedge clock); 

     // Do stuff here .. 
    end 
end 
+0

У вас может быть несколько драйверов переменных, а' S' - переменная type ('reg'), так что его штраф должен иметь блок« initial », подобный этому. – Unn

+0

Возможно, это зависит от компилятора; не компилируется на мой, если я не очищаю начальный блок – nav

+0

, какой компилятор вы используете? – Unn

1

ошибка является результатом этих двух линий:

display_hex h1     //display of A 
(
    .bin   (magA), 
    .hexl   (HEX2), 
    .hexh   (HEX3) 
); 

display_hex h2     //display of sum 
(
    .bin   (S[7:0]), 
    .hexl   (HEX0), 
    .hexh   (HEX1) 
); 

Вот, оказывается у вас есть модуль с именем display_hex, который преобразует 8-битное значение в необходимые цифры для семисегментного дисплея. Вы пытаетесь использовать модуль, как если бы это была функция, а модули - очень НЕ функции. Модули в Verilog (или SystemVerilog, поскольку вы используете, но разница на самом деле является токеном на данном этапе) могут быть, хотя и представляют собой группу аппаратных средств, которая принимает некоторые входы и выплевывает некоторые выходы; и важно отметить, что они являются статическими вещами. Они либо существуют в дизайне, либо нет; так же, как использование микросхем на макете. Верхний модуль представляет собой макет, и модули, которые вы объявляете под этим модулем, являются компонентами, которые вы подключаете к плате. Входы и выходы - это различные соединения (контакты), которые вы должны подключить, чтобы все работало.

Это говорит о том, что всегда блокирует (например, always_ff, который вы используете) формирует способ описания логики и регистров внутри модулей. Таким образом, вы думаете, как назначить переменные /reg внутри них, чтобы описать, как работает аппаратное обеспечение. Если вы посмотрите на свою логику, вы заметите, что объявления модуля зависят от reset; т.е. если заявлено reset, эти модули не будут существовать, что не имеет никакого смысла. Электрические сигналы не приводят к исчезновению целых ИС в цепи! Таким образом, вы должны вытащить вашу декларацию модуля из вашего логического описания вашего acculumator, например, так:

module accumulator (
    ... 
); 
    ... 
    display_hex h1     //display of A 
    (
     .bin   (magA), 
     .hexl   (HEX2), 
     .hexh   (HEX3) 
    ); 

    display_hex h2     //display of sum 
    (
     .bin   (S[7:0]), 
     .hexl   (HEX0), 
     .hexh   (HEX1) 
    ); 
    ... 
    always_ff @(posedge clk, posedge reset) begin 
    // Your accumulator logic here 
    ... 
    end 
endmodule 

Обратите внимание, что объявления модуля для display_hex модулей стоят отдельно, как я заявляю, существует эти модули, не зависимость от чего угодно!

Однако существует целый ряд проблем, с вашим дизайном кроме того, что:

  1. Как вы используете SystemVerilog конструкции (always_ff), вы должны объявить все переменные типа logic, не reg или оставить пустым (то есть input clk должно быть input logic clk, reg signA должно быть logic signA). Тип logic просто делает все проще, так что используйте его :)

  2. В вашем always_ff блоке, вы reset правильно за исключением того, что назначение должно быть действительно NBA (использовать S <= 9'b0;, не S = 9'b0; в if (reset))

  3. Вы используете NBA внутри своего always_ff, что верно, однако, похоже, вам нужно использовать эти значения сразу в следующей логике. Это не будет работать так, как вы ожидаете, или, по крайней мере, оно не будет действовать в течение одного такта. Чтобы исправить это, вам нужно решить, что должно быть регистром и что должно быть просто значением, полученным из промежуточной логики, а затем создать отдельный always_comb для промежуточных значений.

  4. Я делаю предположение, что HEX переменные предназначены для семи дисплеев сегмента, так что они должны, вероятно, по крайней мере, заявил [6:0] HEXn

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

  • Нет связанных вопросов^_^