Verilog HDL всегда & ошибки случая - PullRequest
0 голосов
/ 25 апреля 2020

Я работал над FSM, который реализован с использованием Verilog HDL. В случае определения выходов следующего состояния у меня есть два выхода, которые необходимо назначить. Поэтому я попытался использовать begin и end, чтобы поместить два назначения в один случай. Но это все еще не работает. Я не уверен, что есть какие-то синтаксические ошибки, которые я не могу написать таким способом.

module Vending_FSM(
input [2:0] INPUT,
input CLK,
output REL,
output [3:0] AMT
);

// Declaring state and next_state variable
reg[2:0]    state, next_state;

// Declaring 6 state parameters
parameter
    S0 = 3'b000,    // WAIT
    S1 = 3'b001,    // $5
    S2 = 3'b010,    // $10
    S3 = 3'b011,    // $15
    S4 = 3'b100,    // $20
    S5 = 3'b101;    // $25

// Determning next state transition
always @(posedge CLK)
    begin
    state <= next_state;    // Positive-edge triggering 
    end

// Determing next state input
always @(INPUT or state)
    begin
    case (state)
        S0: case (INPUT)    // WAIT
            3'b000: next_state = S1;    // $5
            3'b001: next_state = S2;    // $10
            3'b010: next_state = S4;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S0;    // $100
            3'b101: next_state = S0;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S1: case (INPUT)    // $5
            3'b000: next_state = S2;    // $5
            3'b001: next_state = S3;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S1;    // $100
            3'b101: next_state = S1;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S2: case (INPUT)    // $10
            3'b000: next_state = S3;    // $5
            3'b001: next_state = S4;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S2;    // $100
            3'b101: next_state = S2;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S3: case (INPUT)    // $15
            3'b000: next_state = S4;    // $5
            3'b001: next_state = S5;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S3;    // $100
            3'b101: next_state = S3;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S4: case (INPUT)    // $20
            3'b000: next_state = S5;    // $5
            3'b001: next_state = S5;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S4;    // $100
            3'b101: next_state = S4;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S5: case (INPUT)    // $25
            3'b000: next_state = S5;    // $5
            3'b001: next_state = S5;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S5;    // $100
            3'b101: next_state = S0;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
    endcase
    end

// Determing next state output
always @(INPUT or state)
    begin
    case (state)
        S0: case (INPUT)    // WAIT
            3'b000: begin
                    REL = 1'b0;     // $5
                    AMT = 4'b0000;
                    end
            3'b001: begin
                    REL = 1'b0;     // $10
                    AMT = 4'b0000;
                    end
            3'b010: begin
                    REL = 1'b0;     // $20
                    AMT = 4'b0000;
                    end
            3'b011: begin
                    REL = 1'b0;     // $50
                    AMT = 4'b0101;
                    end
            3'b100: begin
                    REL = 1'b0;     // $100
                    AMT = 4'b1011;
                    end
            3'b101: begin
                    REL = 1'b0;     // PUR
                    AMT = 4'b0000;
                    end
            3'b110: begin
                    REL = 1'b0;     // REF
                    AMT = 4'b0000;
                    end
        endcase
        S1: case (INPUT)    // $5
            3'b000: begin
                    REL = 1'b0;     // $5
                    AMT = 4'b0000;
                    end
            3'b001: begin
                    REL = 1'b0;     // $10
                    AMT = 4'b0000;
                    end
            3'b010: begin
                    REL = 1'b0;     // $20
                    AMT = 4'b0000;
                    end
            3'b011: begin
                    REL = 1'b0;     // $50
                    AMT = 4'b0110;
                    end
            3'b100: begin
                    REL = 1'b0;     // $100
                    AMT = 4'b1011;
                    end
            3'b101: begin
                    REL = 1'b0;     // PUR
                    AMT = 4'b0000;
                    end
            3'b110: begin
                    REL = 1'b0;     // REF
                    AMT = 4'b0001;
                    end
        endcase
        S2: case (INPUT)    // $10
            3'b000: begin
                    REL = 1'b0;     // $5
                    AMT = 4'b0000;
                    end
            3'b001: begin
                    REL = 1'b0;     // $10
                    AMT = 4'b0000;
                    end
            3'b010: begin
                    REL = 1'b0;     // $20
                    AMT = 4'b0001;
                    end
            3'b011: begin
                    REL = 1'b0;     // $50
                    AMT = 4'b0111;
                    end
            3'b100: begin
                    REL = 1'b0;     // $100
                    AMT = 4'b1011;
                    end
            3'b101: begin
                    REL = 1'b0;     // PUR
                    AMT = 4'b0000;
                    end
            3'b110: begin
                    REL = 1'b0;     // REF
                    AMT = 4'b0010;
                    end
        endcase
        S3: case (INPUT)    // $15
            3'b000: begin
                    REL = 1'b0;     // $5
                    AMT = 4'b0000;
                    end
            3'b001: begin
                    REL = 1'b0;     // $10
                    AMT = 4'b0000;
                    end
            3'b010: begin
                    REL = 1'b0;     // $20
                    AMT = 4'b0010;
                    end
            3'b011: begin
                    REL = 1'b0;     // $50
                    AMT = 4'b1000;
                    end
            3'b100: begin
                    REL = 1'b0;     // $100
                    AMT = 4'b1011;
                    end
            3'b101: begin
                    REL = 1'b0;     // PUR
                    AMT = 4'b0000;
                    end
            3'b110: begin
                    REL = 1'b0;     // REF
                    AMT = 4'b0011;
                    end
        endcase
        S4: case (INPUT)    // $20
            3'b000: begin
                    REL = 1'b0;     // $5
                    AMT = 4'b0000;
                    end
            3'b001: begin
                    REL = 1'b0;     // $10
                    AMT = 4'b0001;
                    end
            3'b010: begin
                    REL = 1'b0;     // $20
                    AMT = 4'b0011;
                    end
            3'b011: begin
                    REL = 1'b0;     // $50
                    AMT = 4'b1001;
                    end
            3'b100: begin
                    REL = 1'b0;     // $100
                    AMT = 4'b1011;
                    end
            3'b101: begin
                    REL = 1'b0;     // PUR
                    AMT = 4'b0000;
                    end
            3'b110: begin
                    REL = 1'b0;     // REF
                    AMT = 4'b0100;
                    end
        endcase
        S5: case (INPUT)    // $25
            3'b000: begin
                    REL = 1'b0;     // $5
                    AMT = 4'b0001;
                    end
            3'b001: begin
                    REL = 1'b0;     // $10
                    AMT = 4'b0010;
                    end
            3'b010: begin
                    REL = 1'b0;     // $20
                    AMT = 4'b0100;
                    end
            3'b011: begin
                    REL = 1'b0;     // $50
                    AMT = 4'b1010;
                    end
            3'b100: begin
                    REL = 1'b0;     // $100
                    AMT = 4'b1011;
                    end
            3'b101: begin
                    REL = 1'b1;     // PUR
                    AMT = 4'b0000;
                    end
            3'b110: begin
                    REL = 1'b0;     // REF
                    AMT = 4'b0101;
                    end
        endcase
    endcase
    end

endmodule

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

REL и AMT должны быть типа reg. Поскольку они были выведены wire типов, которые нельзя назначать всегда в блоках.

module Vending_FSM(
input [2:0] INPUT,
input CLK,
output reg REL,
output reg [3:0] AMT
);

также next_state, REL и AMT являются предполагаемыми защелками, поскольку они не назначаются явно при INPUT равно 3'b111 и state вне S0 - S5. Вы можете либо определить все случаи в операторе case, либо / и иметь присвоение по умолчанию над case константе флопа. Пример:

always @* begin
  // default assignment
  next_state = state;
  // update
  case(state)
    S0: case (INPUT)    // WAIT
        //... your existing code, maybe added 3'b111/default case
    endcase
    // S1..S5: ... your existing code, maybe added case 3'b111/default for INPUT
  default : next_state = S0; // in case state not inside S0..S5
  endcase
end
always @* begin
  // default assignment
  REL = 1'b0;
  ATM = 4'b0000;
  // update
  case(state)
    //... your existing code
  endcase
end

Другие примечания:

always @(INPUT or state) технически исправен, но больше не рекомендуется. Используйте always @* или always @(*) для автоматической чувствительности. Указание сигналов для списка чувствительности было необходимо для Verilog-1995. В Verilog-2001 добавлена ​​автоматическая чувствительность, которая снижает риск неполных списков чувствительности; плюс сокращает ввод.

Для более чистых выходных сигналов и более простого анализа синхронизации я рекомендую переключать выходы. Пример:

always @* begin
  // default assignment
  next_REL = 1'b0;
  next_AMT = 4'b0000;
  // update
  case(state)
    //... your existing code but REL and AMT prefixed with next_
  endcase
end
always @(posedge clk) begin
  state <= next_state;
  REL <= next_REL;
  AMT <= next_AMT;
end
0 голосов
/ 25 апреля 2020
module Vending_FSM(
   input      [2:0] INPUT
  ,input            CLK
  ,output reg       REL
  ,output reg [3:0] AMT
);

// Declaring state and next_state variable
reg[2:0]    state, next_state;
reg         n_AMT,n_REL;

// Declaring 6 state parameters
parameter
    S0 = 3'b000,    // WAIT
    S1 = 3'b001,    // $5
    S2 = 3'b010,    // $10
    S3 = 3'b011,    // $15
    S4 = 3'b100,    // $20
    S5 = 3'b101;    // $25

always@(posedge clk)
    state <= next_state;

// Determing next state input
always@*
    case (state)
        S0: case (INPUT)    // WAIT
            3'b000: next_state = S1;    // $5
            3'b001: next_state = S2;    // $10
            3'b010: next_state = S4;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S0;    // $100
            3'b101: next_state = S0;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S1: case (INPUT)    // $5
            3'b000: next_state = S2;    // $5
            3'b001: next_state = S3;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S1;    // $100
            3'b101: next_state = S1;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S2: case (INPUT)    // $10
            3'b000: next_state = S3;    // $5
            3'b001: next_state = S4;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S2;    // $100
            3'b101: next_state = S2;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S3: case (INPUT)    // $15
            3'b000: next_state = S4;    // $5
            3'b001: next_state = S5;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S3;    // $100
            3'b101: next_state = S3;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S4: case (INPUT)    // $20
            3'b000: next_state = S5;    // $5
            3'b001: next_state = S5;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S4;    // $100
            3'b101: next_state = S4;    // PUR
            3'b110: next_state = S0;    // REF
        endcase
        S5: case (INPUT)    // $25
            3'b000: next_state = S5;    // $5
            3'b001: next_state = S5;    // $10
            3'b010: next_state = S5;    // $20
            3'b011: next_state = S5;    // $50
            3'b100: next_state = S5;    // $100
            3'b101: next_state = S0;    // PUR
            3'b110: next_state = S0;    // REF
          endcase
        default:    next_state = 'x;
    endcase

always @* begin
            n_REL = 1'b0;
            n_AMT = 4'b0;
    case (state)
        S0:        if(INPUT == 3'b100) n_AMT = 4'b1011;
              else if(INPUT == 3'b011) n_AMT = 4'b0101;

        S1:        if(INPUT == 3'b011) n_AMT = 4'b0110;
              else if(INPUT == 3'b100) n_AMT = 4'b1011;
              else if(INPUT == 3'b110) n_AMT = 4'b0001;

        S2:        if(INPUT == 3'b010) n_AMT = 4'b0001;
              else if(INPUT == 3'b011) n_AMT = 4'b0111;
              else if(INPUT == 3'b100) n_AMT = 4'b1011;
              else if(INPUT == 3'b110) n_AMT = 4'b0010;

        S3:        if(INPUT == 3'b010) n_AMT = 4'b0010;
              else if(INPUT == 3'b011) n_AMT = 4'b1000;
              else if(INPUT == 3'b100) n_AMT = 4'b1011;
              else if(INPUT == 3'b110) n_AMT = 4'b0011;

        S4:        if(INPUT == 3'b001) n_AMT = 4'b0001;
              else if(INPUT == 3'b010) n_AMT = 4'b0011;
              else if(INPUT == 3'b011) n_AMT = 4'b1001;
              else if(INPUT == 3'b100) n_AMT = 4'b1011;
              else if(INPUT == 3'b110) n_AMT = 4'b0100;

        S5:        if(INPUT == 3'b000) n_AMT = 4'b0001;
              else if(INPUT == 3'b001) n_AMT = 4'b0010;
              else if(INPUT == 3'b010) n_AMT = 4'b0100;
              else if(INPUT == 3'b011) n_AMT = 4'b1010;
              else if(INPUT == 3'b100) n_AMT = 4'b1011;
              else if(INPUT == 3'b101) n_REL = 1'b1;
              else if(INPUT == 3'b110) n_AMT = 4'b0101;

    endcase
end

always @(posedge clk) begin
    REL <= #1 n_REL;
    AMT <= #1 n_AMT;
end

endmodule
...