ahb_master.vhd
来自「vhdl实现的amba代码」· VHDL 代码 · 共 688 行 · 第 1/2 页
VHD
688 行
--********** htrans *********--***************************--busy if:--write:--count>1 and fifo=1 and trans_reg/=busy and addr_data--count=1 and fifo_empty and addr_data --read:--fifo_hfull and addr_datas_mst_out.htrans <= tmp_htrans;tmp_htrans <= --busy when (mst_state=addr_data and granted='1' and page_fault='0' and dma_count>=2 and ((next_fifo_he='1' and r_mst_out.hwrite='1') or (next_fifo_hf='1' and r_mst_out.hwrite='0'))) elsebusy when (mst_state=addr_data and ((dma_count>=2 and ((fifo_count<=1 and r_mst_out.hwrite='1') or (fifo_count>=fifo_length-1 and r_mst_out.hwrite='0'))) or(dma_count=1 and ((fifo_count<=1 and r_mst_out.hwrite='1') or (fifo_count=fifo_length and r_mst_out.hwrite='0'))))) elsenonseq when (mst_state=addr) elseseq when (mst_state=addr_data) elseidle; --***************************--******** granted bus ******--*************************** process(hclk, hresetn)begin if hresetn='0' then granted <= '0'; elsif hclk'event and hclk='1' then granted <= '0' after 1 ns; if (mst_in.hready='1' and mst_in.hgrant='1') then granted <= '1' after 1 ns; end if; end if;end process;next_fifo_empty <= '1' when ((fifo_count=0 and (fifo_write='0' or (fifo_write=fifo_read))) or (fifo_count=1 and fifo_read='1' and fifo_write='0')) else '0';next_fifo_full <= '1' when ((fifo_count=fifo_length and (fifo_read='0' or (fifo_write=fifo_read))) or (fifo_count=fifo_length-1 and fifo_read='0' and fifo_write='1')) else '0';next_fifo_he <= '1' when ((fifo_count<=1 and (fifo_write='0' or (fifo_write=fifo_read))) or (fifo_count=2 and fifo_read='1' and fifo_write='0')) else '0';next_fifo_hf <= '1' when ((fifo_count>=fifo_length-1 and (fifo_read='0' or (fifo_write=fifo_read))) or (fifo_count=fifo_length-2 and fifo_read='0' and fifo_write='1')) else '0';--next_count_ge2 <= '1' when ((dma_count_ge2='1' and fifo_hwrite='0' and fifo_hread='0') or (dma_count_ge3='1' and (fifo_hwrite='1' or fifo_hread='1'))) else '0'; --***************************--********* old_hburst ******--*************************** process(hclk, hresetn)begin if hresetn='0' then old_hburst <= incr; prior_reg <= slave; elsif hclk'event and hclk='1' then old_hburst <= old_hburst_s after 1 ns; prior_reg <= prior_s after 1 ns; end if;end process;old_hburst_s <= start_hburst when (dma_start.start='1') else old_hburst;prior_s <= start_prior when (dma_start.start='1') else prior_reg;--***************************--*************************** process(hclk,hresetn)begin if hresetn='0' then r_mst_out.haddr <= (others => '0'); r_mst_out.htrans <= "00"; r_mst_out.hlock <= '0'; r_mst_out.hwrite <= '0'; r_mst_out.hsize <= bits32; r_mst_out.hburst <= incr; r_mst_out.hprot <= "0011"; elsif hclk'event and hclk='1' then r_mst_out.haddr <= s_mst_out.haddr after 1 ns; r_mst_out.htrans <= s_mst_out.htrans after 1 ns; r_mst_out.hlock <= s_mst_out.hlock after 1 ns; r_mst_out.hwrite <= s_mst_out.hwrite after 1 ns; r_mst_out.hsize <= s_mst_out.hsize after 1 ns; r_mst_out.hburst <= s_mst_out.hburst after 1 ns; r_mst_out.hprot <= s_mst_out.hprot after 1 ns; end if;end process; s_mst_out.hlock <= start_hlocked when (dma_start.start='1') else r_mst_out.hlock; s_mst_out.hwrite <= start_hwrite when (dma_start.start='1') else r_mst_out.hwrite; s_mst_out.hsize <= start_hsize when (dma_start.start='1') else r_mst_out.hsize;s_mst_out.hburst <= start_hburst when (dma_start.start='1') else incr when (dma_restart='1') else r_mst_out.hburst;s_mst_out.hprot <= start_hprot when (dma_start.start='1') else r_mst_out.hprot;mst_out.hlock <= hlock_t;mst_out.hwrite <= r_mst_out.hwrite;mst_out.hsize <= r_mst_out.hsize; mst_out.hburst <= r_mst_out.hburst;mst_out.hprot <= r_mst_out.hprot;mst_out.haddr <= r_mst_out.haddr;mst_out.hwdata <= fifo_dataout;--not retimed!mst_out.hbusreq <= hbusreq_t; mst_out.htrans <= s_mst_out.htrans;--***************************--********** haddr **********--*************************** old_addr_pr:process(hclk, hresetn)begin if hresetn='0' then old_addr <= (others => '0'); elsif hclk'event and hclk='1' then old_addr <= old_addr_s after 1 ns; end if;end process;old_addr_move:process(mst_state, mst_in, tmp_htrans, r_mst_out)begin if ((mst_state=addr or mst_state=addr_data or mst_state=data) and mst_in.hready='1' and tmp_htrans/=busy and r_mst_out.htrans/=busy) then old_addr_incr <= '1'; else old_addr_incr <= '0'; end if;end process;old_addr_s <= r_mst_out.haddr when (old_addr_incr='1') elsedma_start.extaddr when (dma_start.start='1') elseold_addr;page_fault <= '1' when (page_attention='1' and (pf_incr='1' or pf_wrap4='1' or pf_wrap8='1' or pf_wrap16='1')) else '0';pf_incr <= '1' when (haddr_t(9 downto 2)=0) else '0';pf_wrap4 <= '1' when (haddr_t(3 downto 2)=0 and old_hburst=wrap4) else '0';pf_wrap8 <= '1' when (haddr_t(4 downto 2)=0 and old_hburst=wrap8) else '0';pf_wrap16 <= '1' when (haddr_t(5 downto 2)=0 and old_hburst=wrap16) else '0'; with r_mst_out.hburst selectpage_attention <='1' when incr|incr4|incr8|incr16,'0' when others;with old_hburst selectold_page_attention <='1' when incr|incr4|incr8|incr16,'0' when others;with r_mst_out.hburst selecthaddr_t(9 downto 2) <=r_mst_out.haddr(9 downto 2)+1 when incr|incr4|incr8|incr16,r_mst_out.haddr(9 downto 4)&(r_mst_out.haddr(3 downto 2)+"01") when wrap4,r_mst_out.haddr(9 downto 5)&(r_mst_out.haddr(4 downto 2)+"001") when wrap8,r_mst_out.haddr(9 downto 6)&(r_mst_out.haddr(5 downto 2)+"0001") when wrap16,r_mst_out.haddr(9 downto 2) when others;--"000",--page increment if:--page fault and incr/incr4/incr8/incr16 and old_burst incr/incr4/incr8/incr16s_mst_out.haddr(31 downto 10) <=dma_start.extaddr(31 downto 10) when (dma_start.start='1') else old_addr(31 downto 10) when (mst_state=retry_phase or mst_state=idle_phase) else(r_mst_out.haddr(31 downto 10)+1) when (page_attention='1' and old_page_attention='1' and pf_incr='1' and haddr_incr='1') elser_mst_out.haddr(31 downto 10);s_mst_out.haddr(1 downto 0) <= dma_start.extaddr(1 downto 0) when (dma_start.start='1') else r_mst_out.haddr(1 downto 0);s_mst_out.haddr(9 downto 2) <= dma_start.extaddr(9 downto 2) when (dma_start.start='1') else old_addr(9 downto 2) when (mst_state=retry_phase or mst_state=idle_phase) elser_mst_out.haddr(9 downto 4)&"00" when (page_fault='1' and pf_wrap4='1' and haddr_incr='1') elser_mst_out.haddr(9 downto 5)&"000" when (page_fault='1' and pf_wrap8='1' and haddr_incr='1') else r_mst_out.haddr(9 downto 6)&"0000" when (page_fault='1' and pf_wrap16='1' and haddr_incr='1') else haddr_t(9 downto 2) when (haddr_incr='1') else r_mst_out.haddr(9 downto 2); --haddr_incr_pr:process(mst_state, mst_in, tmp_htrans, r_mst_out)--begin-- if ((mst_state=addr or mst_state=addr_data) and mst_in.hready='1' and tmp_htrans/=busy and r_mst_out.htrans/=busy) then-- or mst_state=data -- haddr_incr <= '1';-- else-- haddr_incr <= '0';-- end if;--end process;--haddr_incr <= '1' when--(mst_in.hready='1' and --(tmp_htrans=nonseq or --((tmp_htrans=seq or tmp_htrans=busy) and r_mst_out.htrans/=busy))) else '0';haddr_incr <= '1' when(mst_in.hready='1' and (tmp_htrans=nonseq or tmp_htrans=seq or tmp_htrans=busy) and r_mst_out.htrans/=busy) else '0';--***************************--********* hbusreq *********--*************************** hbusreq_t <= '1' when((dma_count>0 and mst_state=req_phase) or(dma_count>1 and (mst_state=addr or mst_state=addr_data))) else '0';mst_req <= '1' when (r_mst_out.hwrite='0' or fifo_empty='0') else '0'; --start new master if:--read or--write and fifo_count>=2 or--write and fifo_count=1 and dma_count=1 --***************************--********** hlock *********--*************************** hlock_t <= hbusreq_t and r_mst_out.hlock;--for hlock behaviour different wrt hbusreq change ONLY here!!--***************************--********* eot_int *********--*************************** int_gen:process(hclk, hresetn)begin if hresetn='0' then eot_int_reg <= '0'; elsif hclk'event and hclk='1' then if (mst_state=idle_phase) then eot_int_reg <= '0' after 1 ns; elsif (s_mst_state=idle_phase and mst_running_t='1' and dma_count_s=0) then eot_int_reg <= '1' after 1 ns; end if; end if;end process;eot_int <= eot_int_reg; --***************************--****** mst_running *****--*************************** mst_running_t <= '0' when (mst_state=idle_phase or mst_state=wait_phase or mst_state=req_phase) else '1';mst_running <= mst_running_t;--***************************--******** dma_count ********--*************************** dma_count_pr:process(hclk, hresetn)begin if hresetn='0' then dma_count <= (others => '0'); elsif hclk'event and hclk='1' then dma_count <= dma_count_s after 1 ns; end if;end process; process(dma_start, start_hburst)begin if dma_start.start='1' then case start_hburst is when single => right_count(15 downto 0) <= "0000000000000001"; when incr => right_count(15 downto 0) <= dma_start.count; when wrap4|incr4 => right_count(15 downto 0) <= "0000000000000100"; when wrap8|incr8 => right_count(15 downto 0) <= "0000000000001000" ; when others =>--wrap16|incr16 right_count(15 downto 0) <= "0000000000010000"; end case; else right_count(15 downto 0) <= (others => '-'); end if;end process;dma_count_s <= (others=>'0') when fifo_reset='1' else -- dma_count-1 when (r_mst_out.hwrite='1' and fifo_hread='1') or (r_mst_out.hwrite='0' and fifo_hwrite='1') else dma_count-1 when ((mst_state=addr or mst_state=addr_data) and haddr_incr='1') else dma_count+1 when (mst_state=retry_phase and mst_in.hready='1') else right_count when (dma_start.start='1') else dma_count; dma_restart <= '1' when (mst_state=retry_phase or mst_state=data) else '0';fifo_reset <= '1' when ((mst_state=error_phase) or(mst_in.hresp=ok_resp and r_mst_out.htrans/=busy and r_mst_out.hwrite='1' and mst_in.hready='1' and mst_state=data and dma_count=0)) else '0'; --***************************--***** fifo interface ******--*************************** fifo_write <= fifo_hwrite or m_wrap_in.ask_ok;fifo_read <= fifo_hread or m_wrap_in.take_ok; fifo_datain <= mst_in.hrdata when (fifo_hwrite='1') else m_wrap_in.rdata;m_wrap_out.wdata <= fifo_dataout;--transfer master => fifofifo_hwrite <= '1' when (r_mst_out.hwrite='0' and data_trx='1' and fifo_full='0') else '0';--transfer fifo => masterfifo_hread <= '1' when (r_mst_out.hwrite='1' and data_trx='1' and fifo_empty='0') else '0'; data_trx <= '1' when (mst_in.hready='1' and mst_in.hresp=ok_resp and r_mst_out.htrans/=busy and (mst_state=addr_data or mst_state=data)) else '0'; --***********************************************--master<=>core interface: program/data memories --***********************************************--transfer fifo => core m_wrap_out.take <= '1' when (r_mst_out.hwrite='0' and fifo_empty='0') else '0';--transfer core => fifom_wrap_out.ask <= '1' when (r_mst_out.hwrite='1' and fifo_full='0' and (mst_running_t='1' or dma_count/=0)) else '0'; m_wrap_out.addr <= int_addr; process(hclk, hresetn)begin if hresetn='0' then int_addr <= (others => '0'); int_mod <= (others => '0'); elsif hclk'event and hclk='1' then int_addr <= int_addr_s after 1 ns; int_mod <= int_mod_s after 1 ns; end if;end process;int_mod_s <= dma_start.intmod when (dma_start.start='1') else int_mod; int_page_fault <= '1' when (int_addr_t(9 downto 2)=0 and page_attention='1') else '0'; with r_mst_out.hburst selectint_addr_t(9 downto 2) <=int_addr(9 downto 2)+int_mod(9 downto 2) when incr|incr4|incr8|incr16,int_addr(9 downto 4)&(int_addr(3 downto 2)+"01") when wrap4,int_addr(9 downto 5)&(int_addr(4 downto 2)+"001") when wrap8,int_addr(9 downto 6)&(int_addr(5 downto 2)+"0001") when wrap16,int_addr(9 downto 2) when others;--"000",int_addr_incr <= '1' when ((r_mst_out.hwrite='0' and m_wrap_in.take_ok='1') or (r_mst_out.hwrite='1' and m_wrap_in.ask_ok='1')) else '0';int_addr_s(31 downto 16) <= (others => '0');int_addr_s(15 downto 10) <= (int_addr(15 downto 10)+1) when (int_page_fault='1' and int_addr_incr='1') else dma_start.intaddr(15 downto 10) when (dma_start.start='1') else int_addr(15 downto 10);int_addr_s(1 downto 0) <= dma_start.intaddr(1 downto 0) when (dma_start.start='1') else int_addr(1 downto 0);int_addr_s(9 downto 2) <= int_addr_t(9 downto 2) when (int_addr_incr='1') else dma_start.intaddr(9 downto 2) when (dma_start.start='1') else int_addr(9 downto 2); end rtl;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?