📄 ahbmst_em.vhd
字号:
-------------------------------------------------------------------------------- This file is a part of the GRLIB VHDL IP LIBRARY-- Copyright (C) 2003, Gaisler Research---- This program is free software; you can redistribute it and/or modify-- it under the terms of the GNU General Public License as published by-- the Free Software Foundation; either version 2 of the License, or-- (at your option) any later version.---- This program is distributed in the hope that it will be useful,-- but WITHOUT ANY WARRANTY; without even the implied warranty of-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-- GNU General Public License for more details.---- You should have received a copy of the GNU General Public License-- along with this program; if not, write to the Free Software-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------- Entity: ahbmst_em-- File: ahbmst_em.vhd-- Author: Alf Vaerneus, Gaisler Research-- Description: AMBA AHB Master emulator for simulation purposes only-------------------------------------------------------------------------------- pragma translate_offlibrary IEEE;use IEEE.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;library gaisler;use grlib.devices.all;use gaisler.ambatest.all;library std;use std.textio.all;entity ahbmst_em is generic( hindex : integer := 0; timeoutc : integer := 100; dbglevel : integer := 2 ); port( rst : in std_logic; clk : in std_logic; -- AMBA signals ahbmi : in ahb_mst_in_type; ahbmo : out ahb_mst_out_type; -- TB signals tbi : in tb_in_type; tbo : out tb_out_type );end;architecture tb of ahbmst_em isconstant VERSION : integer := 1;constant hconfig : ahb_config_type := ( 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_AHBMST_EM, 0, VERSION, 0), others => zero32);constant T_O : integer := timeoutc;type state_type is(idle,active,done);type reg_type is record state : state_type; current_word : integer; address : std_logic_vector(31 downto 0); data : std_logic_vector(31 downto 0); tocnt : integer; running : std_logic; longfile : std_logic; active : std_logic; grant : std_logic; ahbmo : ahb_mst_out_type;end record;signal r,rin : reg_type;signal fileahbmo : ahb_mst_out_type;begintb : process(tbi,ahbmi,r,rst)variable v : reg_type;variable status : status_type;variable ready : std_logic;variable ahbm : ahb_mst_out_type;variable newaddress : std_logic_vector(31 downto 0);variable inc : std_logic_vector(3 downto 0);begin v := r; ahbm := AHB_IDLE; newaddress := r.address; v.tocnt := 0; ready := '0'; inc := (others => '0'); ahbm.hconfig := hconfig; if tbi.start = '1' then if (r.running = '0' and r.state = idle) then v.address := tbi.address; status := OK; v.running := '1'; end if; case tbi.command is when RD_SINGLE => ahbm := READ_SINGLE; when RD_INCR => ahbm := READ_INCR; when WR_SINGLE => ahbm := WRITE_SINGLE; when WR_INCR => ahbm := WRITE_INCR; when others => end case; ahbm.hwdata := tbi.data; end if; inc(conv_integer(ahbm.hsize)) := '1'; if ((r.active and not ahbmi.hresp(1)) = '1') then if ahbm.htrans = HTRANS_NONSEQ then ahbm.htrans := HTRANS_SEQ; newaddress := newaddress+inc; end if; if ahbmi.hready = '1' then v.address := r.address + inc; v.current_word := r.current_word+1; end if; if newaddress(9 downto 0) = "0000000000" then ahbm.htrans := HTRANS_NONSEQ; end if; end if; if v.current_word >= tbi.no_words then ahbm.htrans := HTRANS_IDLE; end if; ahbm.haddr := newaddress; if tbi.userfile then if ahbmi.hresp(1) = '0' then v.ahbmo := fileahbmo; v.ahbmo.hwrite := ahbm.hwrite; ahbm.haddr := fileahbmo.haddr; if ahbmi.hready = '1' then v.data := fileahbmo.hwdata; end if; ahbm.hwdata := r.data; if r.longfile = '1' then ahbm.htrans := fileahbmo.htrans; ahbm.hburst := fileahbmo.hburst; ahbm.hsize := fileahbmo.hsize; ahbm.hprot := fileahbmo.hprot; end if; else ahbm := r.ahbmo; end if; end if; if ahbmi.hresp = HRESP_ERROR then status := ERR; elsif r.tocnt = T_O then status := TIMEOUT; end if; case r.state is when idle => if r.running = '1' then v.state := active; end if; when active => v.tocnt := r.tocnt + 1; ahbm.hbusreq := r.running; if (r.grant and ahbmi.hready) = '1' then v.tocnt := 0; end if; if (v.current_word >= tbi.no_words and r.grant = '1' and tbi.userfile = false) then v.running := '0'; ahbm.hbusreq := '0'; end if; if (status /= OK or ((ahbmi.hready and not r.running) = '1' and ahbmi.hresp = HRESP_OKAY)) then v.state := done; ahbm.htrans := HTRANS_IDLE; end if; when done => v.running := '0'; ready := '1'; if tbi.start = '0' then v.state := idle; v.longfile := '0'; v.current_word := 0; end if; when others => end case; if ahbmi.hready = '1' then v.grant := ahbmi.hgrant(hindex); if ahbm.htrans /= HTRANS_IDLE then v.active := r.grant; else v.active := '0'; end if; end if; ahbm.hindex := hindex; if rst = '0' then v.address := (others => '0'); v.state := idle; v.running := '0'; v.current_word := 0; v.tocnt := 0; v.longfile := '0'; v.ahbmo := AHB_IDLE; end if; tbo.ready <= ready; tbo.status <= status; rin <= v; ahbmo <= ahbm;end process;tbo.data <= ahbmi.hrdata when (ahbmi.hready and r.running) = '1';cpur : process (clk)file datafile_write,datafile_read :text;variable L : line;variable dataint : integer;variable datahex : string(1 to 8);variable count : integer;begin if rising_edge (clk) then r <= rin; if tbi.usewfile then case r.state is when idle => if r.running = '1' then file_open(datafile_write,external_name => tbi.wfile(18 downto trimlen(tbi.wfile)), open_kind => write_mode); count := 0; end if; when active => if ((r.active and ahbmi.hready) = '1' and ahbmi.hresp = HRESP_OKAY) then if (tbi.userfile = false or count > 0) then write(L,printhex(ahbmi.hrdata,32)); writeline(datafile_write,L); end if; count := count+1; end if; if rin.state = done then file_close(datafile_write); end if; when done => when others => end case; end if; if tbi.userfile then case r.state is when idle => if r.running = '1' then fileahbmo <= AHB_IDLE; fileahbmo.hwrite <= rin.ahbmo.hwrite; file_open(datafile_read,external_name => tbi.rfile(18 downto trimlen(tbi.rfile)), open_kind => read_mode); readline(datafile_read,L); read(L,dataint); if dataint = 1 then r.longfile <= '1'; else r.longfile <= '0'; end if; end if; when active => if ((ahbmi.hgrant(hindex) and ahbmi.hready) = '1' and ahbmi.hresp = HRESP_OKAY) then if not endfile(datafile_read) then if r.longfile = '1' then readline(datafile_read,L); -- Dummy read for header readline(datafile_read,L); read(L,dataint); fileahbmo.htrans <= conv_std_logic_vector(dataint,2); readline(datafile_read,L); read(L,dataint); fileahbmo.hburst <= conv_std_logic_vector(dataint,3); readline(datafile_read,L); read(L,dataint); fileahbmo.hsize <= conv_std_logic_vector(dataint,3); readline(datafile_read,L); read(L,dataint); fileahbmo.hprot <= conv_std_logic_vector(dataint,4); readline(datafile_read,L); read(L,datahex); fileahbmo.haddr <= conv_std_logic_vector(datahex,32); readline(datafile_read,L); read(L,datahex); fileahbmo.hwdata <= conv_std_logic_vector(datahex,32); else readline(datafile_read,L); -- Dummy read for header readline(datafile_read,L); read(L,datahex); fileahbmo.haddr <= conv_std_logic_vector(datahex,32); readline(datafile_read,L); read(L,datahex); fileahbmo.hwdata <= conv_std_logic_vector(datahex,32); end if; else r.running <= '0'; end if; end if; when done => if tbi.start = '0' then file_close(datafile_read); end if; when others => end case; end if; end if;end process;bootmsg : report_versiongeneric map ("pcimst_em" & tost(hindex) &": PCI Master Emulator rev " & tost(VERSION) &" for simulation purpose only." &" NOT syntheziseable.");end;-- pragma translate_on
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -