mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
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.
This commit is contained in:
commit
361a01259c
@ -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,
|
||||
|
||||
616
dcache.vhdl
616
dcache.vhdl
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;
|
||||
|
||||
25
mmu.vhdl
25
mmu.vhdl
@ -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…
x
Reference in New Issue
Block a user