📄 gendc.vhd
字号:
-- writeback, allocte full line -- $(del) -- read write -- Writeback | Writethrough writeback | writethrough -- +--------+--------+ +--------+--------+ -- hit |<MISS> hit | miss hit |<MISS> hit | miss -- +----+----+ +----+----+ +----+----+ +----+----+ -- | <free>|<dirty>| | | <free>|<dirty>| | -- O1 +--+--+ O1 O3 O5 +--+--+ O4/O6 O6 -- | | | | | -- O3<---O2 O4 O5<---O2 -- | -- O4 -- $(/del) when gendc_wb_fillline => t.cmaddr_src := gdca_no; t.meaddr_src := gdcma_no; t.datain_src := gdcdi_me; t.cmaddr := r.p_address; t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := r.fill_linepos; t.meaddr := (others => '0'); t.meaddr(GDCL_TTAG_U downto GDCL_TTAG_D) := dcmo.tag_line(lin_convint(r.setrep)).tag; t.meaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := r.linepos; t.linepos := so.res(GCML_DC_TLINE_BSZ-1 downto 0); if r.fill_linepos = GDCL_ZERO_C then t.tvalid_src := gdcvalid_new; t.tdirty_src := gdcdirty_new; else t.tvalid_src := gdcvalid_add; t.tdirty_src := gdcdirty_add; end if; t.size := lmd_word; t.read := '1'; t.lock := '0'; t.burst := '1'; if r.linepos = GDCL_LAST_C then t.burst := '0'; end if; if r.stored = '0' then t.wbi.fifo_write := '1'; v.fill_linepos := r.linepos; else if r.wbnext = '0' then v.wbnext := '1'; lin_incdec(r.linepos,v.linepos,'1','1'); end if; if wbo.read_finish_v = '1' then t.mexc := wbo.read_mexc; v.stored := '0'; v.wbnext := '0'; -- return data (on load) if t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D) = r.p_address(GDCL_TLINE_U downto GDCL_TLINE_D) then t.datapi_src := gdcdp_me; end if; t.twrite := '1'; t.dwrite := '1'; if (r.linepos = GDCL_ZERO_C) then v.state := gendc_hit; end if; end if; end if; ------------------------------------------------------------------------------- -- writeback, line flush -- $(del) -- read write -- Writeback | Writethrough writeback | writethrough -- +--------+--------+ +--------+--------+ -- hit |<MISS> hit | miss hit |<MISS> hit | miss -- +----+----+ +----+----+ +----+----+ +----+----+ -- | free|<dirty>| | | free|<dirty>| | -- O1 +--+--+ O1 O3 O5 +--+--+ O4/O6 O6 -- | | | | | -- O3<---O2 O4 O5<---O2 -- | -- O4 -- $(/del) when gendc_wb_wbline => t.cmaddr_src := gdca_no; t.meaddr_src := gdcma_no; t.datain_src := gdcdi_no; t.datapi_src := gdcdp_no; t.linepos := so.res(GCML_DC_TLINE_BSZ-1 downto 0); t.cmaddr := r.p_address; t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := t.linepos; t.meaddr := (others => '0'); t.meaddr(GDCL_TTAG_U downto GDCL_TTAG_D) := dcmo.tag_line(lin_convint(r.setrep)).tag; t.meaddr(GDCL_TLINE_U downto GDCL_TLINE_D) := r.linepos; t.datain := r.o_wr_data; t.size := lmd_word; t.read := '0'; t.lock := '0'; t.burst := '0'; if r.wbready = '0' then --calculating first address v.wbready := '1'; v.dirty(lin_convint(t.linepos)) := '0'; v.linepos := t.linepos; else t.wbi.fifo_write := '1'; -- burst calc t.linepos_lastbit := lin_decode(r.linepos); t.linepos_lastbit := t.linepos_lastbit(CFG_DC_TLINE_SZ-2 downto 0) & "0"; if (r.dirty and t.linepos_lastbit) /= GDCL_ZERO_C then t.burst := '1'; end if; -- buffer cm out if r.wbnext = '0' then v.wbnext := '1'; v.o_wr_data := dcmo.dat_line(lin_convint(r.setrep)).data(t.pos); t.datain := v.o_wr_data; end if; -- next pos if wbo.fifo_stored_v = '1' then v.wbnext := '0'; v.dirty(lin_convint(t.linepos)) := '0'; v.linepos := t.linepos; if r.dirty = GDCL_ZERO_C then v.state := r.state_wbline_next; end if; end if; end if; v.stored := '0'; ------------------------------------------------------------------------------- when gendc_reloadtaddr => t.cmaddr_src := gdca_re; v.state := gendc_hit; v.hold := '0'; ------------------------------------------------------------------------------- when others => end case; if t.mexc = '1' then t.twrite := '0'; t.dwrite := '0'; v.mexc := '1'; end if; -- cm read/write address case t.cmaddr_src is when gdca_no => when gdca_in => t.cmaddr := i.addr_in; when gdca_re => t.cmaddr := i.addr_re; when gdca_lo => t.cmaddr := r.p_address; when others => null; end case; -- mem load/store address (wb input) case t.meaddr_src is when gdcma_no => when gdcma_in => t.meaddr := i.addr_in; when gdcma_re => t.meaddr := i.addr_re; when gdcma_lo => t.meaddr := r.p_address; when others => null; end case; t.setpos := std_logic_vector(conv_unsigned(t.setrep, lin_log2x(CFG_IC_SETS))); if r.hold = '1' then t.setpos := r.setrep; end if; -- data pipeline: read data output [cm|mem]->pipeline t.pos := gdcl_getpos(t.meaddr(GDCL_TLINE_U downto GDCL_TLINE_D)); case t.datapi_src is when gdcdp_no => when gdcdp_me => v.o_wr_data := wbo.read_data; when gdcdp_cm => v.o_wr_data := dcmo.dat_line(lin_convint(t.setpos)).data(t.pos); when others => end case; v.doaddr(1 downto 0) := t.meaddr(1 downto 0); t.o.wr_data := gdcl_readdata ( r.doaddr, r.o_wr_data, CFG_BO_BUS, r.p_sign, r.p_size ); -- write data input (from (pipeline or mem) to (cmem or mem)) case t.datain_src is when gdcdi_no => when gdcdi_in => t.datain := i.data_in; when gdcdi_re => t.datain := i.data_re; when gdcdi_lo => t.datain := r.p_data; when gdcdi_me => t.datain := wbo.read_data; when others => null; end case; -- input tag/data line -- $(del) -- read write -- Writeback | Writethrough Writeback | Writethrough -- +--------+--------+ +--------+--------+ -- hit | miss hit | miss hit | miss hit | miss -- +----+----+ +----+----+ +----+----+ +----+----+ -- | free|dirty | | | free|dirty | | -- O1 +--+--+ O1 O3 <O5> +--+--+ <O4>/O6 O6 -- | | | | | -- O3<---O2 <O4> <O5><---O2 -- | -- <O4> -- $(/del) -- assemble input tag line t.dcmi.addr := t.cmaddr; t.dcmi.tag_line := dcmo.tag_line(lin_convint(t.setpos)); t.newvalid := (others => '0'); t.newvalid := lin_decode(t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D)); case t.tvalid_src is when gdcvalid_old => when gdcvalid_clr => t.dcmi.tag_line.valid := (others => '0'); when gdcvalid_new => t.dcmi.tag_line.valid := t.newvalid; when gdcvalid_add => t.dcmi.tag_line.valid := t.dcmi.tag_line.valid or t.newvalid; end case; t.newdirty := (others => '0'); t.newdirty := lin_decode(t.cmaddr(GDCL_TLINE_U downto GDCL_TLINE_D)); case t.tdirty_src is when gdcdirty_old => when gdcdirty_clr => t.dcmi.tag_line.dirty := (others => '0'); when gdcdirty_new => t.dcmi.tag_line.dirty := t.newdirty; when gdcdirty_add => t.dcmi.tag_line.dirty := t.dcmi.tag_line.dirty or t.newdirty; end case; t.dcmi.tag_line.tag := t.cmaddr(GDCL_TTAG_U downto GDCL_TTAG_D); t.dcmi.tag_write := (others => '0'); t.dcmi.tag_write(lin_convint(t.setpos)) := t.twrite; -- assemble input data line [mem->cache] t.dcmi.dat_line := dcmo.dat_line(lin_convint(t.setpos)); case t.db_src is when gdcdb_mem => t.dcmi.dat_line.data(t.pos) := wbo.read_data; -- on allocate subword when others => end case; t.dcmi.dat_line.data(t.pos) := gdcl_writedata(t.cmaddr(1 downto 0),t.dcmi.dat_line.data(t.pos),t.datain,CFG_BO_BUS,t.size); t.dcmi.dat_write := (others => '0'); t.dcmi.dat_write(lin_convint(t.setpos)) := t.dwrite; -- write buffer in -- $(del) -- read write -- Writeback | Writethrough Writeback | Writethrough -- +--------+--------+ +--------+--------+ -- hit | miss hit | miss hit | miss hit | miss -- +----+----+ +----+----+ +----+----+ +----+----+ -- | free|dirty | | | free|dirty | | -- O1 +--+--+ O1 O3 O5 +--+--+ O4/<O6> <O6> -- | | | | | -- O3<---<O2> O4 O5 <---<O2> -- | -- O4 -- $(/del) t.o.me_mexc := t.mexc; t.o.wr_mexc := r.mexc; t.wbi.fifo_entry.data := t.datain; t.wbi.fifo_entry.addr := t.meaddr; t.wbi.fifo_entry.size := t.size; t.wbi.fifo_entry.read := t.read; t.wbi.fifo_entry.lock := t.lock; t.wbi.fifo_entry.burst := t.burst; case t.wbi.fifo_entry.size is when lmd_word => t.wbi.fifo_entry.addr(1 downto 0) := (others => '0'); when lmd_half => t.wbi.fifo_entry.addr(0) := '0'; when others => end case; -- reset if ( rst = '0' ) then v.hold := '0'; end if; t.o.hold := r.hold; c <= v; o <= t.o; si <= t.si; dcmi <= t.dcmi; wbi <= t.wbi; sr_setfree <= t.sr_setfree; sr_setlock <= t.sr_setlock; sr_useset <= t.sr_useset; -- pragma translate_off vdbg := rdbg; vdbg.cmaddr := t.cmaddr; vdbg.dbg := t; cdbg <= vdbg; -- pragma translate_on end process p0; end process p0; pregs : process (clk, c) begin if rising_edge(clk) then r <= c; -- pragma translate_off rdbg <= cdbg; -- pragma translate_on end if; end process; cnt0: arith_cnt8 port map (rst, clk, si, so); sr0: setrepl generic map ( SETSIZE => CFG_DC_SETS,SETSIZE_logx => GCML_DC_SETS_X ) port map (rst, clk, sr_setfree, sr_setlock, sr_useset, sr_locked, sr_free, sr_setrep_free, sr_setrep_repl); -- pragma translate_off check0 : process (rst) begin assert (CFG_DC_TLINE_SZ <= 8) report "Error: current arith_cntxx component can only count up to 8 positions. Replace with a larger one." severity failure; end process; -- pragma translate_on end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -