mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-03-10 04:24:30 +00:00
loadstore1: Better expression for store data formatting
This rearranges the code used for store data formatting so that the "for i in 0 to 7" loop indexes the output bytes rather than the input bytes. The new expression is formally identical to the old but is easier to synthesize. This reduces the number of LUTs by about 250 on the Artix-7 and improves timing. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
@@ -159,6 +159,7 @@ begin
|
||||
variable done : std_ulogic;
|
||||
variable data_permuted : std_ulogic_vector(63 downto 0);
|
||||
variable data_trimmed : std_ulogic_vector(63 downto 0);
|
||||
variable store_data : std_ulogic_vector(63 downto 0);
|
||||
variable use_second : byte_sel_t;
|
||||
variable trim_ctl : trim_ctl_t;
|
||||
variable negative : std_ulogic;
|
||||
@@ -232,6 +233,23 @@ begin
|
||||
end case;
|
||||
end loop;
|
||||
|
||||
-- Byte reversing and rotating for stores
|
||||
-- Done in the first cycle (when l_in.valid = 1)
|
||||
store_data := r.store_data;
|
||||
if l_in.valid = '1' then
|
||||
byte_offset := unsigned(lsu_sum(2 downto 0));
|
||||
brev_lenm1 := "000";
|
||||
if l_in.byte_reverse = '1' then
|
||||
brev_lenm1 := unsigned(l_in.length(2 downto 0)) - 1;
|
||||
end if;
|
||||
for i in 0 to 7 loop
|
||||
k := (to_unsigned(i, 3) - byte_offset) xor brev_lenm1;
|
||||
j := to_integer(k) * 8;
|
||||
store_data(i * 8 + 7 downto i * 8) := l_in.data(j + 7 downto j);
|
||||
end loop;
|
||||
end if;
|
||||
v.store_data := store_data;
|
||||
|
||||
-- compute (addr + 8) & ~7 for the second doubleword when unaligned
|
||||
next_addr := std_ulogic_vector(unsigned(r.addr(63 downto 3)) + 1) & "000";
|
||||
|
||||
@@ -379,18 +397,6 @@ begin
|
||||
v.first_bytes := byte_sel;
|
||||
v.second_bytes := long_sel(15 downto 8);
|
||||
|
||||
-- Do byte reversing and rotating for stores in the first cycle
|
||||
byte_offset := unsigned(lsu_sum(2 downto 0));
|
||||
brev_lenm1 := "000";
|
||||
if l_in.byte_reverse = '1' then
|
||||
brev_lenm1 := unsigned(l_in.length(2 downto 0)) - 1;
|
||||
end if;
|
||||
for i in 0 to 7 loop
|
||||
k := (to_unsigned(i, 3) xor brev_lenm1) + byte_offset;
|
||||
j := to_integer(k) * 8;
|
||||
v.store_data(j + 7 downto j) := l_in.data(i * 8 + 7 downto i * 8);
|
||||
end loop;
|
||||
|
||||
case l_in.op is
|
||||
when OP_STORE =>
|
||||
req := '1';
|
||||
@@ -465,7 +471,7 @@ begin
|
||||
d_out.nc <= v.nc;
|
||||
d_out.reserve <= v.reserve;
|
||||
d_out.addr <= addr;
|
||||
d_out.data <= v.store_data;
|
||||
d_out.data <= store_data;
|
||||
d_out.byte_sel <= byte_sel;
|
||||
d_out.virt_mode <= v.virt_mode;
|
||||
d_out.priv_mode <= v.priv_mode;
|
||||
|
||||
Reference in New Issue
Block a user