Electronic – Verilog always block w/o posedge or negedge

verilog

I have a basic Verilog block that I wrote to trigger on any change in the signal.

always @ (trigger)  
begin  
  data_out <= data_in;  
end

I expected this to trigger on the rising or falling edge of the trigger. Instead, it tied data_out to data_in. Even when the trigger was in steady state, the output was changing with the input. What am I missing here?

EDIT: I can only use the three signals listed: data_in, data_out, and trigger. The output must initiate on the bit flip of trigger.

Best Answer

Not sure why it would trigger on data_in when written like that unless your synthesising it and simulating at gate level.

always @(posedge clk) in RTL maps to a flip-flop.

always @* in RTL maps to combinatorial logic.

The @* is an auto completed sensitivity list based on any signal which can effect an output (left hand side of =).

Your use of manually specifying a sensitivity list which is not used, to create an output value is not valid for synthesis. As it does not map to hardware.

NB: you should only use <= inside always @posedge blocks (when implying flip-flops) other wise use =.

May be create an edge detection circuit which can be used as an enable for a clocked system.

//Capture Previous trigger values
reg [1:0] trigger_d;
always @(posedge clk) begin
  trigger_d = {trigger_d[0], trigger};
end

reg trigger_toggle;
always @* begin
  //Bitwise XOR reduction operator creates pos & neg edge detect.
  trigger_toggle = ^trigger_d; 
end

always @(posedge clk) begin
  if (trigger_toggle) begin
    data_out <= data_in;  
  end
end

Follow up to question posted in comment for system without dedicated clock:

 logic pos_enable =1'b0;
 logic neg_enable =1'b0;
 always @(posedge trigger) begin
    data_1     <= data_in;  
    pos_enable <= ~pos_enable;
 end

 always @(negedge trigger) begin
    data_2     <= data_in;  
    neg_enable <= ~neg_enable:
 end

 wire sel = pos_enable ^ neg_enable;
 always @* begin
  if (sel) begin
   data_out = data_1;
  end
  else begin
   data_out = data_2;
  end
 end