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?:) 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.sel = x/z: Verilog evaluates both branches and merges bit-by-bit:x.(1’bx) ? 4’b1111 : 4’b1111 → 1111(1’bx) ? 4’b1111 : 4’b0000 → xxxx(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.x/z (intentional for learning).