mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-02-26 08:43:26 +00:00
Use alternative count-leading-zeroes algorithm in the FPU and LSU
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
@@ -46,25 +46,6 @@ architecture behaviour of bit_counter is
|
||||
signal pc32 : sixbit2;
|
||||
signal popcnt : std_ulogic_vector(63 downto 0);
|
||||
|
||||
function edgelocation(v: std_ulogic_vector; nbits: natural) return std_ulogic_vector is
|
||||
variable p: std_ulogic_vector(nbits - 1 downto 0);
|
||||
variable stride: natural;
|
||||
variable b: std_ulogic;
|
||||
variable k: natural;
|
||||
begin
|
||||
stride := 2;
|
||||
for i in 0 to nbits - 1 loop
|
||||
b := '0';
|
||||
for j in 0 to (2**nbits / stride) - 1 loop
|
||||
k := j * stride;
|
||||
b := b or (v(k + stride - 1) and not v(k + (stride/2) - 1));
|
||||
end loop;
|
||||
p(i) := b;
|
||||
stride := stride * 2;
|
||||
end loop;
|
||||
return p;
|
||||
end function;
|
||||
|
||||
begin
|
||||
countzero_r: process(clk)
|
||||
begin
|
||||
|
||||
31
helpers.vhdl
31
helpers.vhdl
@@ -28,6 +28,7 @@ package helpers is
|
||||
|
||||
function bit_reverse(a: std_ulogic_vector) return std_ulogic_vector;
|
||||
function bit_number(a: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function edgelocation(v: std_ulogic_vector; nbits: natural) return std_ulogic_vector;
|
||||
function count_left_zeroes(val: std_ulogic_vector) return std_ulogic_vector;
|
||||
end package helpers;
|
||||
|
||||
@@ -247,16 +248,44 @@ package body helpers is
|
||||
return ret;
|
||||
end;
|
||||
|
||||
-- Assuming the input 'v' is a value of the form 1...10...0,
|
||||
-- the output is the bit number of the rightmost 1 bit in v.
|
||||
-- If v is zero, the result is zero.
|
||||
function edgelocation(v: std_ulogic_vector; nbits: natural) return std_ulogic_vector is
|
||||
variable p: std_ulogic_vector(nbits - 1 downto 0);
|
||||
variable stride: natural;
|
||||
variable b: std_ulogic;
|
||||
variable k: natural;
|
||||
begin
|
||||
stride := 2;
|
||||
for i in 0 to nbits - 1 loop
|
||||
b := '0';
|
||||
for j in 0 to (2**nbits / stride) - 1 loop
|
||||
k := j * stride;
|
||||
b := b or (v(k + stride - 1) and not v(k + (stride/2) - 1));
|
||||
end loop;
|
||||
p(i) := b;
|
||||
stride := stride * 2;
|
||||
end loop;
|
||||
return p;
|
||||
end function;
|
||||
|
||||
-- Count leading zeroes operation
|
||||
-- Assumes the value passed in is not zero (if it is, zero is returned)
|
||||
function count_left_zeroes(val: std_ulogic_vector) return std_ulogic_vector is
|
||||
variable rev: std_ulogic_vector(val'left downto val'right);
|
||||
variable sum: std_ulogic_vector(val'left downto val'right);
|
||||
variable onehot: std_ulogic_vector(val'left downto val'right);
|
||||
variable edge: std_ulogic_vector(val'left downto val'right);
|
||||
variable bn, bn_e, bn_o: std_ulogic_vector(5 downto 0);
|
||||
begin
|
||||
rev := bit_reverse(val);
|
||||
sum := std_ulogic_vector(- signed(rev));
|
||||
onehot := sum and rev;
|
||||
return bit_number(std_ulogic_vector(resize(unsigned(onehot), 64)));
|
||||
edge := sum or rev;
|
||||
bn_e := edgelocation(std_ulogic_vector(resize(signed(edge), 64)), 6);
|
||||
bn_o := bit_number(std_ulogic_vector(resize(unsigned(onehot), 64)));
|
||||
bn := bn_e(5 downto 2) & bn_o(1 downto 0);
|
||||
return bn;
|
||||
end;
|
||||
end package body helpers;
|
||||
|
||||
Reference in New Issue
Block a user