⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmutlb.vhd

📁 leon3 source code 虽然gaisler网站上有下载
💻 VHD
📖 第 1 页 / 共 2 页
字号:
    fault_pro := '0'; fault_pri := '0'; fault_mexc := '0'; fault_trans := '0'; fault_inv := '0'; fault_access := '0';    twi_walk_op_ur := '0'; twi_areq_ur := '0'; twi_aaddr := dr1_dataout&"00";    finish := '0';    store := '0'; v.hold := '0'; savewalk := '0'; tlbo_s1finished := '0';    selstate := '0';         cam_hitaddr := (others => '0');    cam_hit_all := '0';    NEEDSYNC := '0';    for i in entries-1 downto 0 loop      NEEDSYNC := NEEDSYNC or tlbcamo(i).NEEDSYNC;      if (tlbcamo(i).hit) = '1' then        cam_hitaddr(entries_log-1 downto 0) := cam_hitaddr(entries_log-1 downto 0) or conv_std_logic_vector(i, entries_log);        cam_hit_all := '1';      end if;    end loop;        -- tlbcam write operation    tlbcam_tagwrite := TLB_CreateCamWrite( two.data, r.s2_read, two.lvl, tlbi.mmctrl1.ctx, r.s2_data);        -- replacement position    reppos := (others => '0');    if tlb_rep = 0 then      reppos := lruo.pos(entries_log-1 downto 0);      v.touch := '0';    elsif tlb_rep = 1 then      reppos := r.nrep;    end if;    i_reppos := conv_integer(reppos);        -- tw    two_error := two.fault_mexc or two.fault_trans or two.fault_inv;    twACC := two.data(PTE_ACC_U downto PTE_ACC_D);    twLVL := two.lvl;    twPTE := two.data;    twNEEDSYNC := (not two.data(PTE_R)) or ((not r.s2_read) and (not two.data(PTE_M))); -- tw : writeback on next flush    case r.s2_tlbstate is            when idle =>        if (tlbi.s2valid) = '1' then          if r.s2_flush = '1' then            v.s2_tlbstate := pack;          else            v.walk_fault.fault_pri := '0';            v.walk_fault.fault_pro := '0';            v.walk_fault.fault_access := '0';            v.walk_fault.fault_trans := '0';            v.walk_fault.fault_inv := '0';            v.walk_fault.fault_mexc := '0';                        if (r.s2_hm and not tlbi.mmctrl1.tlbdis )  = '1' then              if r.s2_needsync = '1' then                v.s2_tlbstate := sync;              else                finish := '1';              end if;                            if tlb_rep = 0 then                  v.tpos := r.s2_entry; v.touch := '1';  -- touch lru              end if;                          else	      v.s2_entry := reppos;              v.s2_tlbstate := walk;              if tlb_rep = 0 then                lrui_touchmin := '1';             -- lru element consumed              end if;            end if;          end if;        end if;              when walk =>                if (two.finish = '1') then          if ( two_error ) = '0' then            tlbcam_write_op := decode(r.s2_entry);            dr1write := '1';            TLB_CheckFault( twACC, r.s2_isid, r.s2_su, r.s2_read, v.walk_fault.fault_pro, v.walk_fault.fault_pri );          end if;          TLB_MergeData( two.lvl , two.data, r.s2_data, v.walk_transdata.data );          v.walk_transdata.cache := two.data(PTE_C);          v.walk_fault.fault_lvl := two.fault_lvl;          v.walk_fault.fault_access := '0';          v.walk_fault.fault_mexc := two.fault_mexc;          v.walk_fault.fault_trans := two.fault_trans;          v.walk_fault.fault_inv := two.fault_inv;          v.walk_use := '1';                    if ( twNEEDSYNC = '0' or two_error = '1') then            v.s2_tlbstate := pack;          else            v.s2_tlbstate := sync;            v.sync_isw := '1';          end if;                    if tlb_rep = 1 then            if (r.nrep = entries_max) then v.nrep := (others => '0');            else  v.nrep := r.nrep + 1;            end if;          end if;        else          twi_walk_op_ur := '1';        end if;      when pack =>        v.s2_flush := '0';        v.walk_use := '0';        finish := '1';        v.s2_tlbstate := idle;              when sync =>                tlbcam_trans_op := '1';        if ( v.sync_isw = '1') then          -- pte address is currently written to syncram, wait one cycle before issuing twi_areq_ur          v.sync_isw := '0';        else          if (two.finish = '1') then            v.s2_tlbstate := pack;            v.walk_fault.fault_mexc := two.fault_mexc;            if (two.fault_mexc) = '1' then              v.walk_use := '1';            end if;          else            twi_areq_ur := '1';          end if;        end if;              when others =>        v .s2_tlbstate := idle;    end case;    if selstate = '1' then      if tlbi.trans_op = '1' then      elsif tlbi.flush_op = '1' then      end if;    end if;        i_entry := conv_integer(r.s2_entry);          ACC := tlbcamo(i_entry).pteout(PTE_ACC_U downto PTE_ACC_D);    PTE := tlbcamo(i_entry).pteout;    LVL := tlbcamo(i_entry).LVL;    CAC := tlbcamo(i_entry).pteout(PTE_C);        transdata.cache := CAC;    --# fault, todo: should we flush on a fault?    TLB_CheckFault( ACC, r.s2_isid, r.s2_su, r.s2_read, fault_pro, fault_pri );          fault.fault_pro    := '0';    fault.fault_pri    := '0';    fault.fault_access := '0';    fault.fault_mexc   := '0';    fault.fault_trans  := '0';    fault.fault_inv    := '0';    if finish = '1' and (r.s2_flush = '0') then  --protect flush path      fault.fault_pro    := fault_pro;      fault.fault_pri    := fault_pri;      fault.fault_access := fault_access;      fault.fault_mexc   := fault_mexc;      fault.fault_trans  := fault_trans;      fault.fault_inv    := fault_inv;    end if;        if (M_TLB_FASTWRITE /= 0) then      wb_i_entry := conv_integer(cam_hitaddr(entries_log-1 downto 0));            wb_ACC := tlbcamo(wb_i_entry).pteout(PTE_ACC_U downto PTE_ACC_D);      wb_PTE := tlbcamo(wb_i_entry).pteout;      wb_LVL := tlbcamo(wb_i_entry).LVL;      wb_CAC := tlbcamo(wb_i_entry).pteout(PTE_C);      wb_WBNEEDSYNC := tlbcamo(wb_i_entry).WBNEEDSYNC;              wb_transdata.cache := wb_CAC;      TLB_MergeData( wb_LVL, wb_PTE, tlbi.transdata.data, wb_transdata.data );      --# fault, todo: should we flush on a fault?      TLB_CheckFault( wb_ACC, tlbi.transdata.isid, tlbi.transdata.su, tlbi.transdata.read, wb_fault_pro, wb_fault_pri );      wb_transdata.accexc :=  wb_fault_pro or wb_fault_pri or wb_WBNEEDSYNC or (not cam_hit_all);          end if;        --# merge data    TLB_MergeData( LVL, PTE, r.s2_data, transdata.data );        --# reset    if (rst = '0') then      v.s2_flush := '0';      v.s2_tlbstate := idle;      if tlb_rep = 1 then        v.nrep := (others => '0');      end if;      if tlb_rep = 0 then        v.touch := '0';      end if;      v.sync_isw := '0';    end if;        if (finish = '1') or (tlbi.s2valid = '0') then      tlbo_s1finished := '1';      v.s2_hm := cam_hit_all;      v.s2_entry := cam_hitaddr(entries_log-1 downto 0);      v.s2_needsync := NEEDSYNC;      v.s2_data := tlbi.transdata.data;      v.s2_read := tlbi.transdata.read;      v.s2_su := tlbi.transdata.su;      v.s2_isid := tlbi.transdata.isid;      v.s2_flush := tlbi.flush_op;    end if;    -- translation operation tag    mtag := TLB_CreateCamTrans( cam_addr, tlbi.transdata.read, tlbi.mmctrl1.ctx );     tlbcam_tagin := mtag;        -- flush/(probe) operation tag    ftag := TLB_CreateCamFlush( r.s2_data, tlbi.mmctrl1.ctx );     if (r.s2_flush = '1') then      tlbcam_tagin := ftag;    end if;        if r.walk_use = '1' then      transdata  := r.walk_transdata;      fault      := r.walk_fault;    end if;    fault.fault_read   := r.s2_read;    fault.fault_su     := r.s2_su;    fault.fault_isid   := r.s2_isid;    fault.fault_addr   := r.s2_data;        transdata.finish := finish;    transdata.accexc := '0';            twi_adata := PTE;        --# drive signals    tlbo.wbtransdata  <= wb_transdata;        tlbo.transdata    <= transdata;    tlbo.fault        <= fault;    tlbo.nexttrans    <= store;    tlbo.s1finished   <= tlbo_s1finished;    tlbo.tlbcamo <= (others => mmutlbcam_out_none);        twi.walk_op_ur    <= twi_walk_op_ur;    twi.data          <= r.s2_data;    twi.areq_ur       <= twi_areq_ur;    twi.adata         <= twi_adata;    twi.aaddr         <= twi_aaddr;    if tlb_rep = 0 then      lrui.flush        <= r.s2_flush;      lrui.touch        <= r.touch;      lrui.touchmin     <= lrui_touchmin;      lrui.pos          <= (others => '0');      lrui.pos(entries_log-1 downto 0)          <= r.tpos;      lrui.mmctrl1      <= tlbi.mmctrl1;    end if;        dr1_addr          <= r.s2_entry;    dr1_datain        <= two.addr(31 downto 2);    dr1_enable        <= '1';    dr1_write         <= dr1write;        for i in entries-1 downto 0 loop      tlbcami(i).tagin     <= tlbcam_tagin;      tlbcami(i).trans_op  <= tlbi.trans_op; --tlbcam_trans_op;      tlbcami(i).wb_op     <= tlbi.wb_op; --tlbcam_trans_op;      tlbcami(i).flush_op  <= r.s2_flush;      tlbcami(i).mmuen     <= tlbi.mmctrl1.e;      tlbcami(i).tagwrite  <= tlbcam_tagwrite;      tlbcami(i).write_op  <= tlbcam_write_op(i);      tlbcami(i).mset  <= '0';    end loop;  -- i    for i in M_ENT_MAX-1 downto entries loop      tlbcami(i).tagin     <= tlbcam_tfp_none;      tlbcami(i).trans_op  <= '0';      tlbcami(i).wb_op     <= '0';      tlbcami(i).flush_op  <= '0';      tlbcami(i).mmuen     <= '0';      tlbcami(i).tagwrite  <= tlbcam_reg_none;      tlbcami(i).write_op  <= '0';      tlbcami(i).mset  <= '0';    end loop;        c <= v;  end process p0;  p1: process (clk)  begin if rising_edge(clk) then r <= c;  end if;  end process p1;  -- tag-cam tlb entries  tlbcam0: for i in entries-1 downto 0 generate    tag0 : mmutlbcam      generic map ( tlb_type )      port map (rst, clk, tlbcami(i), tlbcamo(i));  end generate tlbcam0;  tlbcamnone: for i in M_ENT_MAX-1 downto entries generate    tlbcamo(i) <= mmutlbcam_out_none;  end generate ;  -- data-ram syncram   dataram : syncram    generic map ( tech => tech, dbits => 30, abits => entries_log)    port map ( clk, dr1_addr, dr1_datain, dr1_dataout, dr1_enable, dr1_write);  -- lru  lru0: if tlb_rep = 0 generate    lru : mmulru      generic map ( entries => entries)      port map ( clk, rst, lrui, lruo );  end generate lru0;end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -