Merge pull request #441 from paulusmack/dcache

This reworks the dcache to try and simplify the logic and alleviate
some of the paths that have been showing up as critical paths in
synthesis. An example is a dependency of the req_is_hit signal on
the wishbone ack, which this series removes. Overall this seems to
have reduced LUT usage and improved timing.
pull/430/merge
Paul Mackerras 2 days ago committed by GitHub
commit 361a01259c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -675,6 +675,7 @@ package common is
atomic_last : std_ulogic;
virt_mode : std_ulogic;
priv_mode : std_ulogic;
tlb_probe : std_ulogic;
addr : std_ulogic_vector(63 downto 0);
data : std_ulogic_vector(63 downto 0); -- valid the cycle after .valid = 1
byte_sel : std_ulogic_vector(7 downto 0);

@ -468,6 +468,7 @@ begin

dcache_0: entity work.dcache
generic map(
SIM => SIM,
LINE_SIZE => 64,
NUM_LINES => DCACHE_NUM_LINES,
NUM_WAYS => DCACHE_NUM_WAYS,

File diff suppressed because it is too large Load Diff

@ -695,7 +695,6 @@ begin
v.flush := '1';
when OP_DCBZ =>
v.dcbz := '1';
v.align_intr := v.nc;
when OP_TLBIE =>
v.tlbie := '1';
v.is_slbia := l_in.insn(7);
@ -713,8 +712,8 @@ begin
v.mmu_op := '1';
when others =>
end case;
v.dc_req := l_in.valid and (v.load or v.store or v.sync or v.dcbz) and not v.align_intr and
not hash_nop;
v.dc_req := l_in.valid and (v.load or v.store or v.sync or v.dcbz or v.tlbie) and
not v.align_intr and not hash_nop;
v.incomplete := v.dc_req and v.two_dwords;

-- Work out controls for load and store formatting
@ -874,7 +873,7 @@ begin
dawrx_match_enable(r3.dawrx(i), r1.req.virt_mode,
r1.req.priv_mode, r1.req.store) then
dawr_match := r1.req.valid and r1.req.dc_req and not r3.dawr_upd and
not (r1.req.touch or r1.req.sync or r1.req.flush);
not (r1.req.touch or r1.req.sync or r1.req.flush or r1.req.tlbie);
end if;
end loop;
stage1_dawr_match <= dawr_match;
@ -919,7 +918,7 @@ begin
v.req.store_data := store_data;
v.req.dawr_intr := dawr_match;
v.wait_dc := r1.req.valid and r1.req.dc_req and not r1.req.load_sp and
not r1.req.incomplete and not r1.req.hashcmp;
not r1.req.incomplete and not r1.req.hashcmp and not r1.req.tlbie;
v.wait_mmu := r1.req.valid and r1.req.mmu_op;
if r1.req.valid = '1' and (r1.req.align_intr or r1.req.hashcmp) = '1' then
v.busy := '1';
@ -1264,6 +1263,7 @@ begin
d_out.sync <= stage1_req.sync;
d_out.nc <= stage1_req.nc;
d_out.reserve <= stage1_req.reserve;
d_out.tlb_probe <= stage1_req.tlbie;
d_out.atomic_qw <= stage1_req.atomic_qw;
d_out.atomic_first <= stage1_req.atomic_first;
d_out.atomic_last <= stage1_req.atomic_last;
@ -1280,6 +1280,7 @@ begin
d_out.sync <= r2.req.sync;
d_out.nc <= r2.req.nc;
d_out.reserve <= r2.req.reserve;
d_out.tlb_probe <= r2.req.tlbie;
d_out.atomic_qw <= r2.req.atomic_qw;
d_out.atomic_first <= r2.req.atomic_first;
d_out.atomic_last <= r2.req.atomic_last;

@ -28,7 +28,6 @@ architecture behave of mmu is

type state_t is (IDLE,
DO_TLBIE,
TLB_WAIT,
PART_TBL_READ,
PART_TBL_WAIT,
PART_TBL_DONE,
@ -195,7 +194,6 @@ begin
variable v : reg_stage_t;
variable dcreq : std_ulogic;
variable tlb_load : std_ulogic;
variable itlb_load : std_ulogic;
variable tlbie_req : std_ulogic;
variable ptbl_rd : std_ulogic;
variable prtbl_rd : std_ulogic;
@ -225,7 +223,6 @@ begin
v.perm_err := '0';
v.rc_error := '0';
tlb_load := '0';
itlb_load := '0';
tlbie_req := '0';
v.inval_all := '0';
ptbl_rd := '0';
@ -309,14 +306,8 @@ begin
end if;

when DO_TLBIE =>
dcreq := '1';
tlbie_req := '1';
v.state := TLB_WAIT;

when TLB_WAIT =>
if d_in.done = '1' then
v.state := RADIX_FINISH;
end if;
v.state := RADIX_FINISH;

when PART_TBL_READ =>
dcreq := '1';
@ -438,20 +429,14 @@ begin

when RADIX_LOAD_TLB =>
tlb_load := '1';
if r.iside = '0' then
dcreq := '1';
v.state := TLB_WAIT;
else
itlb_load := '1';
v.state := IDLE;
end if;
v.state := RADIX_FINISH;

when RADIX_FINISH =>
v.state := IDLE;

end case;

if v.state = RADIX_FINISH or (v.state = RADIX_LOAD_TLB and r.iside = '1') then
if v.state = RADIX_FINISH then
v.err := v.invalid or v.badtree or v.segerror or v.perm_err or v.rc_error;
v.done := not v.err;
end if;
@ -505,11 +490,11 @@ begin
d_out.valid <= dcreq;
d_out.tlbie <= tlbie_req;
d_out.doall <= r.inval_all;
d_out.tlbld <= tlb_load;
d_out.tlbld <= tlb_load and not r.iside;
d_out.addr <= addr;
d_out.pte <= tlb_data;

i_out.tlbld <= itlb_load;
i_out.tlbld <= tlb_load and r.iside;
i_out.tlbie <= tlbie_req;
i_out.doall <= r.inval_all;
i_out.addr <= addr;

Loading…
Cancel
Save