Prev Problem
Next Problem

43. Guard Division by Zero

module safe_div8 (
    input  [7:0] dividend,
    input  [7:0] divisor,
    output [7:0] q,
    output [7:0] r,
    output       div_by_zero
);
    assign div_by_zero = (divisor == 8'd0) ? 1'b1 : 1'b0;
    assign q           = (divisor == 8'd0) ? 8'd0  : (dividend / divisor);
    assign r           = (divisor == 8'd0) ? 8'd0  : (dividend % divisor);
endmodule

 

Synthesizable alternative solution

module safe_div8 (
   input  [7:0] dividend,
   input  [7:0] divisor,
   output [7:0] q,
   output [7:0] r,
   output       div_by_zero
);
   // detect X/Z in divisor (4-state OR)
   wire has_xz = ^{divisor, divisor} === 1'bx;  // reduction XOR trick: X→X
   // 4-state zero compare
   wire eq0 = (divisor == 8'd0);
   reg [7:0] q_calc;
   reg [8:0] rem_calc;
   integer i;
   always @* begin
       q_calc   = 8'd0;
       rem_calc = 9'd0;
       // skip arithmetic if divisor has X/Z
       if (!has_xz && (divisor != 8'd0)) begin
           for (i = 7; i >= 0; i = i - 1) begin
               rem_calc = {rem_calc[7:0], dividend[i]};
               if (rem_calc >= {1'b0, divisor}) begin
                   rem_calc = rem_calc - {1'b0, divisor};
                   q_calc   = {q_calc[6:0], 1'b1};
               end else begin
                   q_calc   = {q_calc[6:0], 1'b0};
               end
           end
       end
   end
   assign q = (eq0 === 1'b1) ? 8'd0 :
              (has_xz || eq0 === 1'bx) ? 8'hxx :
              q_calc;
   assign r = (eq0 === 1'b1) ? 8'd0 :
              (has_xz || eq0 === 1'bx) ? 8'hxx :
              rem_calc[7:0];
   assign div_by_zero = eq0;  // 1, 0, or X
endmodule

💡Remember

  • The conditional (?:) operator is an inline if–else in an expression: y = sel ? a : b;
    • sel=1 → use the then value; sel=0 → use the else value.
  • Crucial with sel = x/z: Verilog evaluates both branches and merges bit-by-bit:
    • If branch values are identical → result is that value.
    • If they differ → result is x.
    • Examples:
      • (1’bx) ? 4’b1111 : 4’b11111111
      • (1’bx) ? 4’b1111 : 4’b0000xxxx
  • In this divider:
    • (divisor == 0) is x if divisor contains x/z, so div_by_zero, q, and r typically become x. That’s good—x-propagation exposes unknown/floating signals instead of hiding them.
  • We guard zero only; we do not sanitize x/z (intentional for learning).