Search code examples
moduleverilogfpgaintel-fpga

Verilog module for a smoke detector and a buzzer


I have Altera DE2-115 FPGA and I try to self-learn Verilog. I decided to make a smoke detector and whenever it smells smoke the buzzer rings (the smoke detector outputs a digital signal).

Here is my trial :

module fire(flag,clock,reset,fire,fire_state,firealarm);
  input        clock, reset, flag, fire;
  output [2:0] fire_state;
  output       firealarm; 

  wire         fire;
  reg    [2:0] fire_state;

  assign firealarm = (fire_state == 1) ? (flag ? 0 : 1) : 0;

  always @ (posedge clock)
    fire_state<= fire ? 1: 0;

end module

But it doesn't run and I think there are a lot of logic errors in this code, any help please? :)


Solution

  • endmodule is one word, you need to remove the space.

    Almost all simulators these days support verilog-2001 or greater so I would encourage the use of the modern port style (ANSI) and not the old verilog 1995 style.

    Your port list goes from:

    module fire(flag,clock,reset,fire,fire_state,firealarm);
    input clock, reset, flag, fire;
    output [2:0] fire_state;
    output firealarm; wire fire;reg[2:0] fire_state;
    

    to :

    module fire(
      input            clock,
      input            reset,
      input            flag,
      input            fire,
      output reg [2:0] fire_state,
      output           firealarm
    );
    

    I have placed each port on a new line with it direction, this makes it much easier to maintain code, it also make it a lot more readable and therefore minimises the chance of typos in connections.

    You have used this syntax a lot (flag?0:1), where you using a boolean to select a boolean there is no need to do this and makes it more difficult to read. If you need to invert it then is a bitwise invert (~). However it is not clear what you are using flag for. for comparrisons and assignments you should be including the width.

    assign firealarm = (fire_state == 3'b1)? (~flag) : 1'b0;
    

    This could also be written out in a combinatorial always block:

    always @* begin
      if (fire_state==3'b001) begin
        firealaram = ~flag;
      else begin
        firealaram = 1'b0;
      end
    end 
    

    fire is 1 bit, fire_state is 3 bits.

    always @ (posedge clock) begin
      fire_state <= {2'b0, fire};
    end