Last active
November 15, 2022 16:21
-
-
Save punzik/89e498612d2487b20aeb9f0bdbd6c22f to your computer and use it in GitHub Desktop.
One-hot state detector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# To run formal verification call SymbiYosys: | |
# $ sby -f onehot_detector.sby | |
[options] | |
mode prove | |
[engines] | |
smtbmc yices | |
[script] | |
read -sv2012 -formal onehot_detector.sv | |
chparam -set WIDTH 21 onehot_detector | |
chparam -set ATOM_WIDTH 6 onehot_detector | |
prep -top onehot_detector | |
[files] | |
onehot_detector.sv |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ps/1ps | |
`default_nettype none | |
module onehot_detector #(parameter WIDTH = 10, | |
parameter ATOM_WIDTH = 4) | |
(input wire [WIDTH-1:0] i_data, | |
output wire o_have, | |
output wire o_many); | |
if (WIDTH <= ATOM_WIDTH) begin | |
logic have, many; | |
assign o_have = have; | |
assign o_many = many; | |
always_comb begin | |
have = 1'b0; | |
many = 1'b0; | |
for (int n = 0; n < WIDTH; n += 1) | |
if (i_data[n]) | |
if (have) many = 1'b1; | |
else have = 1'b1; | |
end | |
end | |
else begin | |
localparam D0_WIDTH = WIDTH >> 1; | |
localparam D1_WIDTH = WIDTH - D0_WIDTH; | |
logic h0, m0; | |
logic h1, m1; | |
onehot_detector #(.WIDTH(D0_WIDTH), .ATOM_WIDTH(ATOM_WIDTH)) | |
d0 (.i_data(i_data[0 +: D0_WIDTH]), | |
.o_have(h0), | |
.o_many(m0)); | |
onehot_detector #(.WIDTH(D1_WIDTH), .ATOM_WIDTH(ATOM_WIDTH)) | |
d1 (.i_data(i_data[D0_WIDTH +: D1_WIDTH]), | |
.o_have(h1), | |
.o_many(m1)); | |
assign o_have = h0 | h1; | |
assign o_many = m0 | m1 | (h0 & h1); | |
end | |
`ifdef FORMAL | |
always_comb | |
if (i_data == '0) begin | |
assert(o_have == 1'b0); | |
assert(o_many == 1'b0); | |
end | |
always_comb | |
if ($onehot(i_data)) begin | |
assert(o_have == 1'b1); | |
assert(o_many == 1'b0); | |
end | |
always_comb | |
if ((i_data != 0) && !$onehot(i_data)) begin | |
assert(o_have == 1'b1); | |
assert(o_many == 1'b1); | |
end | |
`endif | |
endmodule // onehot_detector |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment