Comparator experiments

This commit is contained in:
David Harris 2022-05-03 10:54:30 +00:00
parent 057524b840
commit b4a422f771

View File

@ -30,14 +30,16 @@
`include "wally-config.vh"
module comparator #(parameter WIDTH=32) (
module comparator_sub #(parameter WIDTH=64) (
input logic [WIDTH-1:0] a, b,
output logic [2:0] flags);
logic [WIDTH-1:0] bbar, diff;
logic carry, eq, neg, overflow, lt, ltu;
/*
logic eq, lt, ltu;
// Subtractor implementation
logic [WIDTH-1:0] bbar, diff;
logic carry, neg, overflow;
// subtraction
assign bbar = ~b;
@ -52,7 +54,81 @@ module comparator #(parameter WIDTH=32) (
assign lt = neg ^ overflow;
assign ltu = ~carry;
assign flags = {eq, lt, ltu};
*/
endmodule
module comparator_dc #(parameter WIDTH=64) (
input logic [WIDTH-1:0] a, b,
output logic [2:0] flags);
logic eq, lt, ltu;
assign eq = (a == b);
assign ltu = (a < b);
assign lt = ($signed(a) < $signed(b));
assign flags = {eq, lt, ltu};
endmodule
module comparator_dc_flip #(parameter WIDTH=16) (
input logic [WIDTH-1:0] a, b,
input logic sgnd,
output logic [1:0] flags);
logic eq, lt, ltu;
logic [WIDTH-1:0] af, bf;
// For signed numbers, flip most significant bit
assign af = {a[WIDTH-1] ^ sgnd, a[WIDTH-2:0]};
assign bf = {b[WIDTH-1] ^ sgnd, b[WIDTH-2:0]};
assign eq = (af == bf);
assign lt = (af < bf);
assign flags = {eq, lt};
endmodule
module comparator2 #(parameter WIDTH=64) (
input logic clk, reset,
input logic [WIDTH-1:0] a, b,
output logic [2:0] flags);
logic eq, lt, ltu;
/* verilator lint_off UNOPTFLAT */
// prefix implementation
localparam levels=$clog2(WIDTH);
genvar i;
genvar level;
logic [WIDTH-1:0] e[levels:0];
logic [WIDTH-1:0] l[levels:0];
logic eq2, lt2, ltu2;
// Bitwise logic
assign e[0] = a ~^ b; // bitwise equality
assign l[0] = ~a & b; // bitwise less than unsigned: A=0 and B=1
// Recursion
for (level = 1; level<=levels; level++) begin
for (i=0; i<WIDTH/(2**level); i++) begin
assign e[level][i] = e[level-1][i*2+1] & e[level-1][i*2]; // group equal if both parts equal
assign l[level][i] = l[level-1][i*2+1] | e[level-1][i*2+1] & l[level-1][i*2]; // group less if upper is les or upper equal and lower less
end
end
// Output logic
assign eq2 = e[levels][0]; // A = B if all bits are equal
assign ltu2 = l[levels][0]; // A < B if group is less (unsigned)
// A < B signed if less than unsigned and msb is not < unsigned, or if A negative and B positive
assign lt2 = ltu2 & ~l[0][WIDTH-1] | a[WIDTH-1] & ~b[WIDTH-1];
assign flags = {eq2, lt2, ltu2};
/* verilator lint_on UNOPTFLAT */
endmodule
module comparator #(parameter WIDTH=64) (
input logic [WIDTH-1:0] a, b,
output logic [2:0] flags);
logic eq, lt, ltu;
/* verilator lint_off UNOPTFLAT */
// prefix implementation