【TREQRESP】学习和分析

TREQRESP学习和分析

TREQRESP结构

TREQRESP定义

原有的程序是一个SRIO接口控制模块。用于连接SRIO接口IP核其中Target端的TREQ和TResp两个端口。
TReq是指Target端的请求端口;
TResp是至Target端的Response响应端口。
XILINX的SRIO IP核使用的数据帧结构:
NWRITE(Normal WRITE 常规写模式) NWRITE_R(Normal WRITE Response,带响应的常规写模式) SWRITE(Stream WRITE,数据流写模式,连续写) NRead(常规读模式)
在这里插入图片描述
在这里插入图片描述


TREQRESP代码(VHDL版本)

输入代码块

1.导入库文件

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

2.信号端口

entity TREQRESP is
    Port ( 
    --系统时钟、复位信号------
	clk : in STD_LOGIC;
    rst : in STD_LOGIC;
    --Status input interface linkup表示是否连接入系统----------------
    linkup			: in  std_logic;--linkup表示是否连接入系统
    --Config interface配置接口 设备自己的id地址----------------------
    self_id			: in  std_logic_vector(15 downto 0);-- 设备自己的id地址
    --Target request input interface request端口---------
    treq_tvalid		: in  std_logic;
    treq_tready		: out std_logic;
    treq_tlast		: in  std_logic;
    treq_tdata		: in  std_logic_vector(63 downto 0);
    treq_tkeep		: in  std_logic_vector( 7 downto 0);
    treq_tuser		: in  std_logic_vector(31 downto 0);
    --Target response output interface response端口--------
    tresp_tvalid	: out std_logic;
    tresp_tready	: in  std_logic;
    tresp_tlast		: out std_logic;
    tresp_tdata		: out std_logic_vector(63 downto 0);
    tresp_tkeep		: out std_logic_vector( 7 downto 0);
    tresp_tuser		: out std_logic_vector(31 downto 0);
    --Addr Remap 地址重映射-------------------------------
    maping1_base     : in  std_logic_vector(15 downto 0);
    maping1_high     : in  std_logic_vector(15 downto 0);
    maping1_target   : in  std_logic_vector(31 downto 0);
    maping2_base     : in  std_logic_vector(15 downto 0);
    maping2_high     : in  std_logic_vector(15 downto 0);
    maping2_target   : in  std_logic_vector(31 downto 0);   
	--DoorBell buffer fifo interface DBFIFO-----------
    db_fifo_wren	: out std_logic;
    db_fifo_data	: out std_logic_vector(63 downto 0);
    --NWriteR/NWrite/SWrite-buf interface ------
	WA_addr		: out std_logic_vector( 7 downto 0);--地址
	WA_wren		: out std_logic_vector( 0 downto 0);--写使能
	WA_data_wr	: out std_logic_vector(63 downto 0);--数据总线
	--AxiRam Control interface AXI控制RAM--------------------
	WAstart		: out std_logic;					--AXi写
	WAidle		: in  std_logic;
	WAcount		: out std_logic_vector(31 downto 0);
	WAaddr		: out std_logic_vector(31 downto 0);
    --NRead-buf interface RAM---------------------------
	RA_addr		: out std_logic_vector( 7 downto 0);--读地址
	RA_data_rd	: in  std_logic_vector(63 downto 0);--读数据
    --AxiRam Control interface AXI控制RAM--------------------
    RAstart		: out std_logic;					--Axi读
    RAidle		: in  std_logic;
    RAcount		: out std_logic_vector(31 downto 0);
    RAaddr		: out std_logic_vector(31 downto 0)
    );
end TREQRESP;

3.TREQRESP状态机输出段

architecture Behavioral of TREQRESP is

	
	signal treq_tready_w	: std_logic:='0';
	signal regReqHead		: std_logic_vector(63 downto 0):=x"0000000000000000";
	signal TID				: std_logic_vector( 7 downto 0):=x"00";
	signal FTYPE			: std_logic_vector( 3 downto 0):=x"0";
	signal TTYPE			: std_logic_vector( 3 downto 0):=x"0";
	signal SIZE				: std_logic_vector( 7 downto 0):=x"00";
	signal ADDR				: std_logic_vector(33 downto 0):="00"&x"00000000";
	signal DBINFO           : std_logic_vector(15 downto 0):=x"0000";
	signal TUSER			: std_logic_vector(31 downto 0):=x"00000000";
	signal regLast			: std_logic:='0';
	signal cntsNswrWA2axi	: std_logic_vector( 3 downto 0):=x"0";
	signal cntsNrdRAaxi		: std_logic_vector( 3 downto 0):=x"0";
	signal cntTrans			: std_logic_vector( 7 downto 0):=x"00";
	signal cntsNrdRespData	: std_logic_vector( 7 downto 0):=x"00";	--回复数据包计数器,回复到了第几个数据包
	signal tresp_tvalid_w	: std_logic:='0';
	
	type state_type is ( sReset, sIdle,
					 sWaitHead, sGotHead,
					 sNswrGetData, sNswrResp, sNswrWA2axi, sNswrWAwaitdone, sNswrFinish,
					 sNrdRAaxi, sNrdRAwaitdone, sNrdRespHead, sNrdRespHead2, sNrdRespData, sNrdFinish,
					 sDbWrInfo, sDbResp, sDbFinish,
					 sError );
	---状态解释
	--
	signal state,next_state : state_type:=sReset;	
begin
	--output logic-------------------------------------------------------
	tresp_logic: process( state, FTYPE, TTYPE, TID, self_id, TUSER, RA_data_rd, cntsNrdRespData, SIZE ) begin
		case state is
		when sNswrResp =>--NWRITE_R或者SWRITE
			if (FTYPE=x"5" and TTYPE=x"5") then--NWRITE_R
				tresp_tvalid_w 	<= '1';	--应该是对方(即IP,I端)要写,并且是需要回应的写,因此我们需要发一个包回应,包长为1所以直接tlat置高
				tresp_tlast		<= '1';
			else--在此状态但不是NWRITE_R的处理,不回复数据
				tresp_tvalid_w 	<= '0';
				tresp_tlast		<= '0';
			end if;
			tresp_tdata		<= TID & x"d04000"&x"00000000";--NWRITE_R的回复指定格式
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--将自己的id和接受到TUSER低16位拼接
		when sDbResp =>--收到DB需要回复
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '1';
			tresp_tdata		<= TID & x"d04000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--逻辑与上述一致(所以上述的回复也是一个DB	)
		when sNrdRespHead =>--NREAD RESPOND的包头响应
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '0';--因为还要发送数据包,所以不last
			tresp_tdata		<= TID & x"d84000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);	
		when sNrdRespData =>--NREAD RESPOND的数据响应
			tresp_tvalid_w 	<= '1';	
			tresp_tdata		<= RA_data_rd;
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) ) then--数到最后一个就拉高
				tresp_tlast	<= '1';
			else
				tresp_tlast	<= '0';
			end if;	
		when others =>
			tresp_tvalid_w 	<= '0';
			tresp_tlast		<= '0';
			tresp_tdata		<= x"0000000000000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
		end case;
	end process;
	tresp_tvalid <= tresp_tvalid_w;
	--应该相当于assign,应该是这个值还要在其他地方使用,因为VHDL定义的out类型不能在构造体内部使用,除非定义为buffer
	--这一点和verilog不同,详见【参考书《VHDL硬件描述语言与数字逻辑电路设计(第五版)》p30】

信号初始化,默认当前状态机state和下一个状态机next_state为sReset状态

signal treq_tready_w	: std_logic:='0';
	signal regReqHead		: std_logic_vector(63 downto 0):=x"0000000000000000";
	signal TID				: std_logic_vector( 7 downto 0):=x"00";
	signal FTYPE			: std_logic_vector( 3 downto 0):=x"0";
	signal TTYPE			: std_logic_vector( 3 downto 0):=x"0";
	signal SIZE				: std_logic_vector( 7 downto 0):=x"00";
	signal ADDR				: std_logic_vector(33 downto 0):="00"&x"00000000";
	signal DBINFO           : std_logic_vector(15 downto 0):=x"0000";
	signal TUSER			: std_logic_vector(31 downto 0):=x"00000000";
	signal regLast			: std_logic:='0';
	signal cntsNswrWA2axi	: std_logic_vector( 3 downto 0):=x"0";
	signal cntsNrdRAaxi		: std_logic_vector( 3 downto 0):=x"0";
	signal cntTrans			: std_logic_vector( 7 downto 0):=x"00";
	signal cntsNrdRespData	: std_logic_vector( 7 downto 0):=x"00";	--回复数据包计数器,回复到了第几个数据包
	signal tresp_tvalid_w	: std_logic:='0';
	
	type state_type is ( sReset, sIdle,
					 sWaitHead, sGotHead,
					 sNswrGetData, sNswrResp, sNswrWA2axi, sNswrWAwaitdone, sNswrFinish,
					 sNrdRAaxi, sNrdRAwaitdone, sNrdRespHead, sNrdRespHead2, sNrdRespData, sNrdFinish,
					 sDbWrInfo, sDbResp, sDbFinish,
					 sError );
	---状态解释
	--
	signal state,next_state : state_type:=sReset;	
状态机响应段
--output logic-------------------------------------------------------
	tresp_logic: process( state, FTYPE, TTYPE, TID, self_id, TUSER, RA_data_rd, cntsNrdRespData, SIZE ) begin
		case state is
		when sNswrResp =>--NWRITE_R和SWRITE共同使用sNswrResq状态
			if (FTYPE=x"5" and TTYPE=x"5") then --NWRITE_R响应
				tresp_tvalid_w 	<= '1';	--应该是对方(即IP,I端)要写,并且是需要回应的写,因此我们需要发一个包回应,包长为1所以直接tlat置高
				tresp_tlast		<= '1'; --tlast是相应数据
			else--在此状态但不是NWRITE_R的处理,不回复数据
				tresp_tvalid_w 	<= '0';
				tresp_tlast		<= '0';
			end if;
			tresp_tdata		<= TID & x"d04000"&x"00000000";--NWRITE_R的回复指定格式
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--将自己的id和接受到TUSER低16位拼接
		when sDbResp =>--收到DB需要回复
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '1';
			tresp_tdata		<= TID & x"d04000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--逻辑与上述一致(所以上述的回复也是一个DB	)
		when sNrdRespHead =>--NREAD RESPOND的包头响应
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '0';--因为还要发送数据包,所以不last
			tresp_tdata		<= TID & x"d84000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);	
		when sNrdRespData =>--NREAD RESPOND的数据响应
			tresp_tvalid_w 	<= '1';	
			tresp_tdata		<= RA_data_rd;
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) ) then--数到最后一个就拉高last,响应
				tresp_tlast	<= '1';
			else
				tresp_tlast	<= '0';
			end if;	
		when others =>
			tresp_tvalid_w 	<= '0';
			tresp_tlast		<= '0';
			tresp_tdata		<= x"0000000000000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
		end case;
	end process;
	tresp_tvalid <= tresp_tvalid_w;
	--应该相当于assign,应该是这个值还要在其他地方使用,因为VHDL定义的out类型不能在构造体内部使用,除非定义为buffer
	--这一点和verilog不同,详见【参考书《VHDL硬件描述语言与数字逻辑电路设计(第五版)》p30】

4.AxiRam Control interface AXI控制RAM

RAstart_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sNrdRAaxi and cntsNrdRAaxi<x"3" ) then 
			RAstart<='1';
		else 
			RAstart<='0'; 
		end if;
	end if; end process;
RAcount <= x"00000020";--输出恒定值
RAaddr_logic: process(clk) begin if rising_edge(clk) then
		RAaddr <= ADDR(31 downto 0);
end if; end process;
	RA_addr_logic: process( state, tresp_tvalid_w, tresp_tready, cntsNrdRespData ) begin
		if ( state=sNrdRespHead or state=sNrdRespHead2 ) then
			RA_addr <= x"00";--以上两个state置0
		elsif ( tresp_tvalid_w='1' and tresp_tready='1' ) then
			RA_addr <= cntsNrdRespData+1;--回送数据计数器和地址之间的映射关系
		else
			RA_addr <= cntsNrdRespData+1;
		end if;
	end process;

状态机转移段

	FSM_StateChange_logic: process(clk) begin if rising_edge(clk) then
	if ( rst='1' or linkup='0' ) then --复位信号有效 或者 没有接入系统
		state <= sReset;
	else
		case state is
		when sReset =>
			state <= sIdle;
		when sIdle =>
			state <= sWaitHead;
		when sWaitHead =>
			if (treq_tvalid='1' and treq_tready_w='1') then --request请求模块数据有效并且准备好
				state <= sGotHead;
			else
				state <= state;
			end if;
		when sGotHead =>
			if ( regLast='1' ) then --reglast 读取了last信号,响应后开始进行RAM读
				if ( FTYPE=x"2" ) then
					state <= sNrdRAaxi; -- NRead AXI RAM状态
				elsif ( FTYPE=x"a" ) then
					state <= sDbWrInfo; -- 数据写入FIFO状态
				else
					state <= sIdle;
				end if;
			else
				if ( FTYPE=x"5" or FTYPE=x"6" ) then 
					state <= sNswrGetData;-- NWrite\SWrite 模式得到数据
				else
					state <= sIdle;
				end if;		
			end if;
		when sNswrGetData =>
			if (treq_tvalid='1' and treq_tready_w='1' and treq_tlast='1') then
				state <= sNswrResp;
			else
				state <= state;
			end if;
		when sNswrResp =>
			if ( tresp_tready='1' ) then
				state <= sNswrWA2axi;
			else
				state <= state;
			end if;
		when sNswrWA2axi =>
			if ( cntsNswrWA2axi>=x"6" ) then
				state <= sNswrWAwaitdone;
			else
				state <= state;
			end if;
		when sNswrWAwaitdone =>
			if ( WAidle='1' ) then
				state <= sNswrFinish;
			else
				state <= state;
			end if;
		when sNswrFinish =>
			state <= sIdle;
		when sNrdRAaxi =>
			if ( cntsNrdRAaxi>=x"6") then
				state <= sNrdRAwaitdone;
			else
				state <= state;
			end if;
		when sNrdRAwaitdone =>
			if ( RAidle='1' ) then
				state <= sNrdRespHead;
			else
				state <= state;
			end if;
		when sNrdRespHead =>
			if ( tresp_tready='1' ) then
				state <= sNrdRespHead2;
			else
				state <= state;
			end if;
		when sNrdRespHead2 =>
			state <= sNrdRespData;
		when sNrdRespData =>
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) and tresp_tready='1' and tresp_tvalid_w='1') then
				state <= sNrdFinish;
			else
				state <= state;
			end if;
		when sNrdFinish =>
			state <= sIdle;
		when sDbWrInfo =>
			state <= sDbResp;
		when sDbResp =>
			if ( tresp_tready='1' ) then
				state <= sDbFinish;
			else
				state <= state;
			end if;
		when sDbFinish =>
			state <= sIdle;
		when others =>
			state <= sReset;
		end case;
	end if;
	end if; end process;

TREQRESP状态图

rst=1或者linkup=0
treq_tvalid=1和treq_tready_w=1
命令不对
reglast=1和FTYPE=2
reglast=1和FTYPE=a
reglast=0和FTYPE=5或6
treq_tvalid=1和treq_tready_w=1和treq_tlast=1
tresp_tready=1
cntsNswrWA2axi>=6
WAidle=1 AXI RAM写空闲
tresp_tready=1
cntsNrdRAaxi>=6
RAidle AXI RAM 读空闲
tresp_tready=1
cntsNrdRespData>=SIZE和tresp_tready=1和tresp_tvalid_w=1
SReset 重启
Sidle 空闲
SWaitHead 等待头帧
sGotHead 收获头帧
SNrdRAaxi 读模式下Axi
SDBWrInfo DB写入FIFO数据
SNswrGetData NWrite\SWrite模式得到数据
SNswrResp NWrite\SWrite响应状态
SNswrwA2axi AXI写到RAM状态
SNswrAwaitdone 等待完成状态
SNswrFinish 结束状态
SDBresp DB响应状态
SDBfinish DB 结束状态
SNRdAwaitdone Nread 等待完成信号
SNrdRespHead Nread响应第一个Head状态
SNrdRespHead2 Nread响应第二个Head状态
SNrdRespdata Nread响应数据 状态
SNrdFinish 结束状态
SReset 重启状态:此状态rst复位信号有效或者linkup未连接到系统中时进行复位。其余时刻自动进入Sidle 空闲状态。
regReqHead模块
regReqHead_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then -- SReset状态接收regHead复位
			regReqHead <= x"0000000000000000";
		elsif ( state=sWaitHead and treq_tvalid='1' ) then
			regReqHead <= treq_tdata;
		else
			regReqHead <= regReqHead;
		end if;
	end if; end process;
译码模块
TID_FTYPE_TTYPE_SIZE_ADDR_TUSER_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then --SReset状态复位TID等信号
			TID		<= x"00";
			FTYPE	<= x"0";
			TTYPE	<= x"0";
			SIZE	<= x"00";
			ADDR	<= "00"&x"00000000";
			DBINFO  <= x"0000";
			TUSER	<= x"00000000";
			regLast <= '0';
Sidle 空闲状态:自动进入SWaitHead 等待头帧状态。用于其他状态复位使用。
regReqHead模块
regReqHead_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then -- Sidle状态接收regHead复位
			regReqHead <= x"0000000000000000";
		elsif ( state=sWaitHead and treq_tvalid='1' ) then
			regReqHead <= treq_tdata;
		else
			regReqHead <= regReqHead;
		end if;
	end if; end process;
译码模块
TID_FTYPE_TTYPE_SIZE_ADDR_TUSER_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then --SIdle状态复位TID等信号
			TID		<= x"00";
			FTYPE	<= x"0";
			TTYPE	<= x"0";
			SIZE	<= x"00";
			ADDR	<= "00"&x"00000000";
			DBINFO  <= x"0000";
			TUSER	<= x"00000000";
			regLast <= '0';
SWaitHead 等待头帧状态:treq_tvalid请求端有效='1’和treq_tready_w请求端准备好='1’时,进入SGotHead收获头帧状态。
when sWaitHead =>
			if (treq_tvalid='1' and treq_tready_w='1') then --treq_tvalid请求端有效='1'和treq_tready_w请求端准备好='1'时
				state <= sGotHead;
			else
				state <= state;
			end if;
treq_tready_w控制模块
treq_tready_w_logic: process(state) begin 
		case state is
		when sWaitHead | sNswrGetData =>  --在sWaitHead 等待头帧状态下request请求端准备好treq_tready_w <= '1';
			treq_tready_w <= '1';
		when others =>
			treq_tready_w <= '0';
		end case;
	end process;
	treq_tready <= treq_tready_w;	
regReqHead模块

regReqHead不清楚用途,目前只有这一个模块有,后续仿真模块进一步验证。

	regReqHead_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then
			regReqHead <= x"0000000000000000";
		elsif ( state=sWaitHead and treq_tvalid='1' ) then --在SWaitHead 等待头帧状态下request请求有效treq_tvalid='1' ,读取请求数据到regRegHead数据
			regReqHead <= treq_tdata; -- treq_tdata外界请求数据,输入状态
		else
			regReqHead <= regReqHead;
		end if;
	end if; end process;
译码模块
TID_FTYPE_TTYPE_SIZE_ADDR_TUSER_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then
			TID		<= x"00";
			FTYPE	<= x"0";
			TTYPE	<= x"0";
			SIZE	<= x"00";
			ADDR	<= "00"&x"00000000";
			DBINFO  <= x"0000";
			TUSER	<= x"00000000";
			regLast <= '0';
		elsif ( state=sWaitHead and treq_tvalid='1' ) then --在SWaitHead 等待头帧状态下,treq_tvalid=1(为输入信号)request请求有效时,进行数据解析
			TID		<= treq_tdata(63 downto 56);
			FTYPE	<= treq_tdata(55 downto 52);--FTYPE译码
			TTYPE	<= treq_tdata(51 downto 48);
			SIZE	<= treq_tdata(43 downto 36);
			--ADDR	<= treq_tdata(33 downto 0);
			ADDR(33 downto 32) <= treq_tdata(33 downto 32);--ADDR重定向
			if    (treq_tdata(31 downto 16)>=maping1_base and treq_tdata(31 downto 16)<=maping1_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping1_base&x"0000")+maping1_target;
            elsif (treq_tdata(31 downto 16)>=maping2_base and treq_tdata(31 downto 16)<=maping2_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping2_base&x"0000")+maping2_target;
            else
                ADDR(31 downto 0) <= treq_tdata(31 downto 0);
            end if;
            DBINFO  <= treq_tdata(31 downto 16);
			TUSER	<= treq_tuser;
			regLast <= treq_tlast;	
SGotHead 收获头帧状态:对头帧进行分析,从而选择进入SNread模式\DB模式\NWrite或SWrite模式
when sGotHead => --对收获数据进行判断进入对应命令模式
			if ( regLast='1' ) then
				if ( FTYPE=x"2" ) then
					state <= sNrdRAaxi; --进入Nread模式
				elsif ( FTYPE=x"a" ) then
					state <= sDbWrInfo; --进入DB FIFO信息写入模式
				else
					state <= sIdle; --命令不符进入SIdle 空闲状态
				end if;
			else
				if ( FTYPE=x"5" or FTYPE=x"6" ) then
					state <= sNswrGetData; --进入NWrite\SWrite 读取数据模式
				else
					state <= sIdle;
				end if;		
			end if;
接收头帧译码模块

regLast信号出现在接收头帧译码模块。

TID_FTYPE_TTYPE_SIZE_ADDR_TUSER_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then
			TID		<= x"00";
			FTYPE	<= x"0";
			TTYPE	<= x"0";
			SIZE	<= x"00";
			ADDR	<= "00"&x"00000000";
			DBINFO  <= x"0000";
			TUSER	<= x"00000000";
			regLast <= '0';
		elsif ( state=sWaitHead and treq_tvalid='1' ) then 
			TID		<= treq_tdata(63 downto 56);
			FTYPE	<= treq_tdata(55 downto 52);--FTYPE译码
			TTYPE	<= treq_tdata(51 downto 48);
			SIZE	<= treq_tdata(43 downto 36);
			--ADDR	<= treq_tdata(33 downto 0);
			ADDR(33 downto 32) <= treq_tdata(33 downto 32);--ADDR重定向
			if    (treq_tdata(31 downto 16)>=maping1_base and treq_tdata(31 downto 16)<=maping1_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping1_base&x"0000")+maping1_target;
            elsif (treq_tdata(31 downto 16)>=maping2_base and treq_tdata(31 downto 16)<=maping2_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping2_base&x"0000")+maping2_target;
            else
                ADDR(31 downto 0) <= treq_tdata(31 downto 0);
            end if;
            DBINFO  <= treq_tdata(31 downto 16); --treq_tdata是个输入信号
			TUSER	<= treq_tuser; --treq_luser是个输入信号
			regLast <= treq_tlast;	 --regLast来自treq_tlast,treq_last是个输入信号
		else
			TID		<= TID;
			FTYPE	<= FTYPE;
			TTYPE	<= TTYPE;
			SIZE	<= SIZE;
			ADDR	<= ADDR;
			DBINFO  <= DBINFO;
			TUSER	<= TUSER;
			regLast <= regLast;
		end if;
	end if; end process;
sNswrGetData NWrite\SWrite读取数据状态:在req请求端valid有效 ready准备好 last响应了时,进入NWirte\SWrite响应状态,除了treq_tready外都是输入信号(tready在SWaitHead置为有效)。不满足一直保持该状态。
when sNswrGetData =>
			if (treq_tvalid='1' and treq_tready_w='1' and treq_tlast='1') then --treq请求valid有效 ready准备好 last响应了时,进入NWirte\SWrite响应状态,除了treq_tready外都是输入信号
				state <= sNswrResp;
			else
				state <= state;
			end if;
treq_tready_w_logic模块:在sWaitHead等待头帧或SNswrGetData Nwrite\SWrite数据接受状态treq_tready_w为1,treq_tready信号来源于treq_tready_w_logic模块
treq_tready_w_logic: process(state) begin
		case state is
		when sWaitHead | sNswrGetData =>
			treq_tready_w <= '1';
		when others =>
			treq_tready_w <= '0';
		end case;
	end process;
	treq_tready <= treq_tready_w;
WA_ram_logic模块:Write AXI RAM 模块,进行wr_en写使能、addr地址,data_wr写数据。
WA_ram_logic: process(clk) begin
	if rising_edge(clk) then
		case state is
		when sNswrGetData =>
			if ( treq_tvalid='1' and treq_tready_w='1' ) then
				WA_wren 	<= "1";
			else
				WA_wren 	<= "0";
			end if;
			WA_addr		<= cntTrans;
			WA_data_wr	<= treq_tdata;
		when others =>
			WA_addr		<= x"00";
			WA_wren 		<= "0";
			WA_data_wr	<= x"0000000000000000";
		end case;
	end if;
	end process;
SNswrResp 响应状态:当tresp_tready响应 准备好时,进入SNswrWA2axi 读取状态,更改response相应端 信号。
when sNswrResp =>
			if ( tresp_tready='1' ) then
				state <= sNswrWA2axi;
			else
				state <= state;
			end if;
cntTrans_logic: process(clk) begin
	if rising_edge(clk) then	
		if ( state=sNswrGetData ) then
			if (treq_tvalid='1' and treq_tready_w='1') then
				cntTrans <= cntTrans + 1;
			else
				cntTrans <= cntTrans;
			end if;
		elsif ( state=sNswrResp or state=sNswrWA2axi or state=sNswrWAwaitdone or state=sNswrFinish ) then --状态在SWrite\NWrite响应状态,cntTrans<=cntTrans
			cntTrans <= cntTrans;
		else
			cntTrans <= x"00";
		end if;
	end if;
	end process;
回复数据包计数器模块:回复收到了第几个数据包
cntsNrdRespData_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sNrdRespData and tresp_tvalid_w='1' and tresp_tready='1') then
			cntsNrdRespData <= cntsNrdRespData+1;
		elsif ( state=sNrdRAaxi or state=sNrdRAwaitdone or state=sNrdRespHead  ) then
			cntsNrdRespData <= x"00";
		else
			cntsNrdRespData <= cntsNrdRespData;
		end if;
	end if; end process;
tresp response响应模块
tresp_logic: process( state, FTYPE, TTYPE, TID, self_id, TUSER, RA_data_rd, cntsNrdRespData, SIZE ) begin
		case state is
		when sNswrResp =>--NWRITE_R或SWRITE
			if (FTYPE=x"5" and TTYPE=x"5") then--NWRITE_R
				tresp_tvalid_w 	<= '1';	--应该是对方(即IP,I端)要写,并且是需要回应的写,因此我们需要发一个包回应,包长为1所以直接tlat置高
				tresp_tlast		<= '1';
			else--在此状态但不是NWRITE_R的处理,不回复数据
				tresp_tvalid_w 	<= '0';
				tresp_tlast		<= '0';
			end if;
			tresp_tdata		<= TID & x"d04000"&x"00000000";--NWRITE_R的回复指定格式
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--将自己的id和接受到TUSER低16位拼接
SNswrWA2axi AXI写到RAM状态:计数器cntsNswrWA2axi计数到6时,进入sNswrWAwaitdone 等待完成状态。
when sNswrWA2axi =>
			if ( cntsNswrWA2axi>=x"6" ) then
				state <= sNswrWAwaitdone;
			else
				state <= state;
			end if;
sNswrWA2axi计数模块

7分频计数,拖延时间从而使状态SNswrWA2axi状态到SNswrAwaitdone 等待结束状态。

cntsNswrWA2axi_logic: process(clk) begin 
	if rising_edge(clk) then
		if ( state=sNswrWA2axi ) then 
			cntsNswrWA2axi <= cntsNswrWA2axi + 1;
		else
			cntsNswrWA2axi <= x"0";
		end if;
	end if; end process;
RAM 地址转换模块
cntTrans_logic: process(clk) begin
	if rising_edge(clk) then	
		if ( state=sNswrGetData ) then
			if (treq_tvalid='1' and treq_tready_w='1') then
				cntTrans <= cntTrans + 1;
			else
				cntTrans <= cntTrans;
			end if;
		elsif ( state=sNswrResp or state=sNswrWA2axi or state=sNswrWAwaitdone or state=sNswrFinish ) then
			cntTrans <= cntTrans;
		else
			cntTrans <= x"00";
		end if;
	end if;
	end process;
AXI RAM读起始模块
--AXI RAM读起始模块
	RAstart_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sNrdRAaxi and cntsNrdRAaxi<x"3" ) then 
			RAstart<='1';
		else 
			RAstart<='0'; 
		end if;
	end if; end process;
	RAcount <= x"00000020";--输出恒定值
	RAaddr_logic: process(clk) begin if rising_edge(clk) then
		RAaddr <= ADDR(31 downto 0);
	end if; end process;
AXI RAM写控制模块
--AXI RAM写控制模块
	WA_ctrl_logic: process(clk) begin
	if rising_edge(clk) then
		case state is
		when sNswrWA2axi =>
			if ( cntsNswrWA2axi<=x"3") then
				WAstart <= '0';
			else
				WAstart <= '1';			
			end if;
			WAcount <= x"000000"&cntTrans;
			WAaddr	<= ADDR(31 downto 0);
		when sNswrWAwaitdone =>
			WAstart <= '0';
			WAcount <= x"000000"&cntTrans;
			WAaddr	<= ADDR(31 downto 0);
		when others =>
			WAstart <= '0';
			WAcount <= x"00000000";
			WAaddr 	<= x"00000000";
		end case;
	end if;
	end process;	
sNswrAwaitdone 等待结束状态:WAidle为1时,进入SNswrFinish结束状态。
when sNswrWAwaitdone =>
			if ( WAidle='1' ) then --写AXI 总线空闲
				state <= sNswrFinish;
			else
				state <= state;
			end if;
sMswrFinish 结束状态:一个周期跳转SIdle 空闲状态。
when sNswrFinish =>
			state <= sIdle;
SDBWrInfo DB写入FIFO数据状态:
DB的FIFO控制逻辑
DB的FIFO控制逻辑
	db_fifo_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sDbWrInfo ) then
			db_fifo_wren <= '1';--使能FIFO写
			--db_fifo_data <= x"00" & TID & ADDR(31 downto 16) & TUSER;
			db_fifo_data <= x"00" & TID & DBINFO & TUSER;--FIFO写数据包装{补充的位宽8,TID位宽8,DBINFO位宽16,TUSER位宽32}=1个包
		else
			db_fifo_wren <= '0';
			db_fifo_data <= x"0000000000000000";
		end if;
	end if; end process;
解析、地址重映射模块
--解析、地址重映射模块
	TID_FTYPE_TTYPE_SIZE_ADDR_TUSER_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then
			TID		<= x"00";
			FTYPE	<= x"0";
			TTYPE	<= x"0";
			SIZE	<= x"00";
			ADDR	<= "00"&x"00000000";
			DBINFO  <= x"0000";
			TUSER	<= x"00000000";
			regLast <= '0';
		elsif ( state=sWaitHead and treq_tvalid='1' ) then
			TID		<= treq_tdata(63 downto 56);
			FTYPE	<= treq_tdata(55 downto 52);--FTYPE译码
			TTYPE	<= treq_tdata(51 downto 48);
			SIZE	<= treq_tdata(43 downto 36);
			--ADDR	<= treq_tdata(33 downto 0);
			ADDR(33 downto 32) <= treq_tdata(33 downto 32);--ADDR重定向
			if    (treq_tdata(31 downto 16)>=maping1_base and treq_tdata(31 downto 16)<=maping1_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping1_base&x"0000")+maping1_target;
            elsif (treq_tdata(31 downto 16)>=maping2_base and treq_tdata(31 downto 16)<=maping2_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping2_base&x"0000")+maping2_target;
            else
                ADDR(31 downto 0) <= treq_tdata(31 downto 0);
            end if;
            DBINFO  <= treq_tdata(31 downto 16);
			TUSER	<= treq_tuser;
			regLast <= treq_tlast;	
		else
			TID		<= TID;
			FTYPE	<= FTYPE;
			TTYPE	<= TTYPE;
			SIZE	<= SIZE;
			ADDR	<= ADDR;
			DBINFO  <= DBINFO;
			TUSER	<= TUSER;
			regLast <= regLast;
		end if;
	end if; end process;
SDBresp DB响应状态:收到DB需要回复
when sDbResp =>
			if ( tresp_tready='1' ) then
				state <= sDbFinish;
			else
				state <= state;
			end if;
when sDbResp =>--收到DB需要回复
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '1';
			tresp_tdata		<= TID & x"d04000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--逻辑与上述一致(所以上述的回复也是一个DB	)
SDBfinishDB结束状态:一个周期返回SIdle。
when sDbFinish =>
			state <= sIdle;
sNrdRAaxi Nread AXI RAM 状态:计数到6时,等于7分频,延时到达sNswrWAwaitdone Nread 等待结束状态
when sNswrWA2axi =>
			if ( cntsNswrWA2axi>=x"6" ) then
				state <= sNswrWAwaitdone;
			else
				state <= state;
			end if;
sNrdRaxi延迟模块
--sNrdRaxi延迟模块
	cntsNrdRAaxi_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sNrdRAaxi ) then
			cntsNrdRAaxi <= cntsNrdRAaxi + 1;
		else
			cntsNrdRAaxi <= x"0";
		end if;
	end if; end process;	
sNrdRAwaitdone Nread 等待结束状态:RAidle=1 AXI RAM 空闲(输入信号)时,进入sNrdRespHead Nread 响应第一个头帧状态。
when sNrdRAwaitdone =>
			if ( RAidle='1' ) then
				state <= sNrdRespHead;
			else
				state <= state;
			end if;
AXI RAM写控制模块
--AXI RAM写控制模块
	WA_ctrl_logic: process(clk) begin
	if rising_edge(clk) then
		case state is
		when sNswrWA2axi =>
			if ( cntsNswrWA2axi<=x"3") then
				WAstart <= '0';
			else
				WAstart <= '1';			
			end if;
			WAcount <= x"000000"&cntTrans;
			WAaddr	<= ADDR(31 downto 0);
		when sNswrWAwaitdone =>
			WAstart <= '0';
			WAcount <= x"000000"&cntTrans;
			WAaddr	<= ADDR(31 downto 0);
		when others =>
			WAstart <= '0';
			WAcount <= x"00000000";
			WAaddr 	<= x"00000000";
		end case;
	end if;
	end process;	
sNrdRespHead Nread 响应第一个头帧状态:tresp_tready=1时,进入sNrdRespHead2 Nread 响应第二个头帧状态。
when sNrdRespHead =>
			if ( tresp_tready='1' ) then
				state <= sNrdRespHead2;
			else
				state <= state;
			end if;
sNrdRespHead2 Nread 响应第二个头帧状态:一个周期进入sNrdRespData SNread 响应数据状态。
when sNrdRespHead2 =>
			state <= sNrdRespData;
收到数据计数器模块
--回复数据包计数器模块:回复到了第几个数据包
	cntsNrdRespData_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sNrdRespData and tresp_tvalid_w='1' and tresp_tready='1') then
			cntsNrdRespData <= cntsNrdRespData+1;
		elsif ( state=sNrdRAaxi or state=sNrdRAwaitdone or state=sNrdRespHead  ) then
			cntsNrdRespData <= x"00";
		else
			cntsNrdRespData <= cntsNrdRespData;
		end if;
	end if; end process;
when sNrdRespData =>--NREAD RESPOND的数据响应
			tresp_tvalid_w 	<= '1';	
			tresp_tdata		<= RA_data_rd;
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) ) then--数到最后一个就拉高
				tresp_tlast	<= '1';
			else
				tresp_tlast	<= '0';
			end if;	
sNrdRespData SNread 响应数据状态:回复的数据到达输入的SIZE、tresp_tready响应端准备好='1’和tresp_tvalid_w相应端有效=‘1’,进入sNrdFinish结束状态
when sNrdRespData =>
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) and tresp_tready='1' and tresp_tvalid_w='1') then
				state <= sNrdFinish;
			else
				state <= state;
			end if;
when sNrdRespData =>--NREAD RESPOND的数据响应
			tresp_tvalid_w 	<= '1';	
			tresp_tdata		<= RA_data_rd;
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) ) then--数到最后一个就拉高
				tresp_tlast	<= '1';
			else
				tresp_tlast	<= '0';
			end if;	
sNrdFinish Nread结束状态:一个周期到SIdle 空闲状态。
when sNrdFinish =>
			state <= sIdle;

源代码

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 2020/11/15 14:54:16
-- Design Name: 
-- Module Name: TREQRESP - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity TREQRESP is
    Port ( 
	clk : in STD_LOGIC;
    rst : in STD_LOGIC;
    --Status input interface-----------------
    linkup			: in  std_logic;
    --Config interface-----------------------
    self_id			: in  std_logic_vector(15 downto 0);
    --Target request input interface---------
    treq_tvalid		: in  std_logic;
    treq_tready		: out std_logic;
    treq_tlast		: in  std_logic;
    treq_tdata		: in  std_logic_vector(63 downto 0);
    treq_tkeep		: in  std_logic_vector( 7 downto 0);
    treq_tuser		: in  std_logic_vector(31 downto 0);
    --Target response output interface--------
    tresp_tvalid	: out std_logic;
    tresp_tready	: in  std_logic;
    tresp_tlast		: out std_logic;
    tresp_tdata		: out std_logic_vector(63 downto 0);
    tresp_tkeep		: out std_logic_vector( 7 downto 0);
    tresp_tuser		: out std_logic_vector(31 downto 0);
    --Addr Remap-------------------------------
    maping1_base     : in  std_logic_vector(15 downto 0);
    maping1_high     : in  std_logic_vector(15 downto 0);
    maping1_target   : in  std_logic_vector(31 downto 0);
    maping2_base     : in  std_logic_vector(15 downto 0);
    maping2_high     : in  std_logic_vector(15 downto 0);
    maping2_target   : in  std_logic_vector(31 downto 0);   
	--DoorBell buffer fifo interface-----------
    db_fifo_wren	: out std_logic;
    db_fifo_data	: out std_logic_vector(63 downto 0);
    --NWriteR/NWrite/SWrite-buf interface------
	WA_addr		: out std_logic_vector( 7 downto 0);--地址
	WA_wren		: out std_logic_vector( 0 downto 0);--写使能
	WA_data_wr	: out std_logic_vector(63 downto 0);--数据总线
	--AxiRam Control interface--------------------
	WAstart		: out std_logic;					--AXi写
	WAidle		: in  std_logic;
	WAcount		: out std_logic_vector(31 downto 0);
	WAaddr		: out std_logic_vector(31 downto 0);
    --NRead-buf interface---------------------------
	RA_addr		: out std_logic_vector( 7 downto 0);--读地址
	RA_data_rd	: in  std_logic_vector(63 downto 0);--读数据
    --AxiRam Control interface--------------------
    RAstart		: out std_logic;					--Axi读
    RAidle		: in  std_logic;
    RAcount		: out std_logic_vector(31 downto 0);
    RAaddr		: out std_logic_vector(31 downto 0)
    );
end TREQRESP;

architecture Behavioral of TREQRESP is

	
	signal treq_tready_w	: std_logic:='0';
	signal regReqHead		: std_logic_vector(63 downto 0):=x"0000000000000000";
	signal TID				: std_logic_vector( 7 downto 0):=x"00";
	signal FTYPE			: std_logic_vector( 3 downto 0):=x"0";
	signal TTYPE			: std_logic_vector( 3 downto 0):=x"0";
	signal SIZE				: std_logic_vector( 7 downto 0):=x"00";
	signal ADDR				: std_logic_vector(33 downto 0):="00"&x"00000000";
	signal DBINFO           : std_logic_vector(15 downto 0):=x"0000";
	signal TUSER			: std_logic_vector(31 downto 0):=x"00000000";
	signal regLast			: std_logic:='0';
	signal cntsNswrWA2axi	: std_logic_vector( 3 downto 0):=x"0";
	signal cntsNrdRAaxi		: std_logic_vector( 3 downto 0):=x"0";
	signal cntTrans			: std_logic_vector( 7 downto 0):=x"00";
	signal cntsNrdRespData	: std_logic_vector( 7 downto 0):=x"00";	--回复数据包计数器,回复到了第几个数据包
	signal tresp_tvalid_w	: std_logic:='0';
	
	type state_type is ( sReset, sIdle,
					 sWaitHead, sGotHead,
					 sNswrGetData, sNswrResp, sNswrWA2axi, sNswrWAwaitdone, sNswrFinish,
					 sNrdRAaxi, sNrdRAwaitdone, sNrdRespHead, sNrdRespHead2, sNrdRespData, sNrdFinish,
					 sDbWrInfo, sDbResp, sDbFinish,
					 sError );
	---状态解释
	--
	signal state,next_state : state_type:=sReset;	
begin
	--output logic-------------------------------------------------------
	tresp_logic: process( state, FTYPE, TTYPE, TID, self_id, TUSER, RA_data_rd, cntsNrdRespData, SIZE ) begin
		case state is
		when sNswrResp =>--???这是什么状态捏NWRITE_R或者SWRITE?
			if (FTYPE=x"5" and TTYPE=x"5") then--NWRITE_R
				tresp_tvalid_w 	<= '1';	--应该是对方(即IP,I端)要写,并且是需要回应的写,因此我们需要发一个包回应,包长为1所以直接tlat置高
				tresp_tlast		<= '1';
			else--在此状态但不是NWRITE_R的处理,不回复数据
				tresp_tvalid_w 	<= '0';
				tresp_tlast		<= '0';
			end if;
			tresp_tdata		<= TID & x"d04000"&x"00000000";--NWRITE_R的回复指定格式
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--将自己的id和接受到TUSER低16位拼接
		when sDbResp =>--收到DB需要回复
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '1';
			tresp_tdata		<= TID & x"d04000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);--逻辑与上述一致(所以上述的回复也是一个DB	)
		when sNrdRespHead =>--NREAD RESPOND的包头响应
			tresp_tvalid_w 	<= '1';	
			tresp_tlast		<= '0';--因为还要发送数据包,所以不last
			tresp_tdata		<= TID & x"d84000"&x"00000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);	
		when sNrdRespData =>--NREAD RESPOND的数据响应
			tresp_tvalid_w 	<= '1';	
			tresp_tdata		<= RA_data_rd;
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) ) then--数到最后一个就拉高
				tresp_tlast	<= '1';
			else
				tresp_tlast	<= '0';
			end if;	
		when others =>
			tresp_tvalid_w 	<= '0';
			tresp_tlast		<= '0';
			tresp_tdata		<= x"0000000000000000";
			tresp_tkeep		<= x"ff";
			tresp_tuser		<= self_id & TUSER(15 downto 0);
		end case;
	end process;
	tresp_tvalid <= tresp_tvalid_w;
	--应该相当于assign,应该是这个值还要在其他地方使用,因为VHDL定义的out类型不能在构造体内部使用,除非定义为buffer
	--这一点和verilog不同,详见【参考书p30】
	

	
	--AXI RAM读起始模块
	RAstart_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sNrdRAaxi and cntsNrdRAaxi<x"3" ) then 
			RAstart<='1';
		else 
			RAstart<='0'; 
		end if;
	end if; end process;
	RAcount <= x"00000020";--输出恒定值
	RAaddr_logic: process(clk) begin if rising_edge(clk) then
		RAaddr <= ADDR(31 downto 0);
	end if; end process;
	
	--AXI RAM读地址模块
	RA_addr_logic: process( state, tresp_tvalid_w, tresp_tready, cntsNrdRespData ) begin
		if ( state=sNrdRespHead or state=sNrdRespHead2 ) then
			RA_addr <= x"00";--以上两个state置0
		elsif ( tresp_tvalid_w='1' and tresp_tready='1' ) then
			RA_addr <= cntsNrdRespData+1;--回送数据计数器和地址之间的映射关系
		else
			RA_addr <= cntsNrdRespData+1;
		end if;
	end process;
	
	--AXI RAM写控制模块
	WA_ram_logic: process(clk) begin
	if rising_edge(clk) then
		case state is
		when sNswrGetData =>
			if ( treq_tvalid='1' and treq_tready_w='1' ) then
				WA_wren 	<= "1";
			else
				WA_wren 	<= "0";
			end if;
			WA_addr		<= cntTrans;
			WA_data_wr	<= treq_tdata;
		when others =>
			WA_addr		<= x"00";
			WA_wren 		<= "0";
			WA_data_wr	<= x"0000000000000000";
		end case;
	end if;
	end process;
	
	--AXI RAM写控制模块
	WA_ctrl_logic: process(clk) begin
	if rising_edge(clk) then
		case state is
		when sNswrWA2axi =>
			if ( cntsNswrWA2axi<=x"3") then
				WAstart <= '0';
			else
				WAstart <= '1';			
			end if;
			WAcount <= x"000000"&cntTrans;
			WAaddr	<= ADDR(31 downto 0);
		when sNswrWAwaitdone =>
			WAstart <= '0';
			WAcount <= x"000000"&cntTrans;
			WAaddr	<= ADDR(31 downto 0);
		when others =>
			WAstart <= '0';
			WAcount <= x"00000000";
			WAaddr 	<= x"00000000";
		end case;
	end if;
	end process;	
	
	--!!!DB的FIFO控制逻辑
	db_fifo_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sDbWrInfo ) then
			db_fifo_wren <= '1';--使能FIFO写
			--db_fifo_data <= x"00" & TID & ADDR(31 downto 16) & TUSER;
			db_fifo_data <= x"00" & TID & DBINFO & TUSER;--FIFO写数据包装{补充的位宽8,TID位宽8,DBINFO位宽16,TUSER位宽32}=1个包
		else
			db_fifo_wren <= '0';
			db_fifo_data <= x"0000000000000000";
		end if;
	end if; end process;




	
	--状态转换逻辑
	----------------------------------------------------------------------------	
	FSM_StateChange_logic: process(clk) begin if rising_edge(clk) then
	if ( rst='1' or linkup='0' ) then
		state <= sReset;
	else
		case state is
		when sReset =>
			state <= sIdle;
		when sIdle =>
			state <= sWaitHead;
		when sWaitHead =>
			if (treq_tvalid='1' and treq_tready_w='1') then
				state <= sGotHead;
			else
				state <= state;
			end if;
		when sGotHead =>
			if ( regLast='1' ) then
				if ( FTYPE=x"2" ) then
					state <= sNrdRAaxi;
				elsif ( FTYPE=x"a" ) then
					state <= sDbWrInfo;
				else
					state <= sIdle;
				end if;
			else
				if ( FTYPE=x"5" or FTYPE=x"6" ) then
					state <= sNswrGetData;
				else
					state <= sIdle;
				end if;		
			end if;
		when sNswrGetData =>
			if (treq_tvalid='1' and treq_tready_w='1' and treq_tlast='1') then
				state <= sNswrResp;
			else
				state <= state;
			end if;
		when sNswrResp =>
			if ( tresp_tready='1' ) then
				state <= sNswrWA2axi;
			else
				state <= state;
			end if;
		when sNswrWA2axi =>
			if ( cntsNswrWA2axi>=x"6" ) then
				state <= sNswrWAwaitdone;
			else
				state <= state;
			end if;
		when sNswrWAwaitdone =>
			if ( WAidle='1' ) then
				state <= sNswrFinish;
			else
				state <= state;
			end if;
		when sNswrFinish =>
			state <= sIdle;
		when sNrdRAaxi =>
			if ( cntsNrdRAaxi>=x"6") then
				state <= sNrdRAwaitdone;
			else
				state <= state;
			end if;
		when sNrdRAwaitdone =>
			if ( RAidle='1' ) then
				state <= sNrdRespHead;
			else
				state <= state;
			end if;
		when sNrdRespHead =>
			if ( tresp_tready='1' ) then
				state <= sNrdRespHead2;
			else
				state <= state;
			end if;
		when sNrdRespHead2 =>
			state <= sNrdRespData;
		when sNrdRespData =>
			if ( cntsNrdRespData>=(SIZE(7 downto 3)) and tresp_tready='1' and tresp_tvalid_w='1') then
				state <= sNrdFinish;
			else
				state <= state;
			end if;
		when sNrdFinish =>
			state <= sIdle;
		when sDbWrInfo =>
			state <= sDbResp;
		when sDbResp =>
			if ( tresp_tready='1' ) then
				state <= sDbFinish;
			else
				state <= state;
			end if;
		when sDbFinish =>
			state <= sIdle;
		when others =>
			state <= sReset;
		end case;
	end if;
	end if; end process;

-- treq_tready处理模块
	--assist logic------------------------------------------------------
	treq_tready_w_logic: process(state) begin
		case state is
		when sWaitHead | sNswrGetData =>
			treq_tready_w <= '1';
		when others =>
			treq_tready_w <= '0';
		end case;
	end process;
	treq_tready <= treq_tready_w;	
	
--regReqHead模块
	regReqHead_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then
			regReqHead <= x"0000000000000000";
		elsif ( state=sWaitHead and treq_tvalid='1' ) then
			regReqHead <= treq_tdata;
		else
			regReqHead <= regReqHead;
		end if;
	end if; end process;

--解析、地址重映射模块
	TID_FTYPE_TTYPE_SIZE_ADDR_TUSER_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sReset or state=sIdle ) then
			TID		<= x"00";
			FTYPE	<= x"0";
			TTYPE	<= x"0";
			SIZE	<= x"00";
			ADDR	<= "00"&x"00000000";
			DBINFO  <= x"0000";
			TUSER	<= x"00000000";
			regLast <= '0';
		elsif ( state=sWaitHead and treq_tvalid='1' ) then
			TID		<= treq_tdata(63 downto 56);
			FTYPE	<= treq_tdata(55 downto 52);--FTYPE译码
			TTYPE	<= treq_tdata(51 downto 48);
			SIZE	<= treq_tdata(43 downto 36);
			--ADDR	<= treq_tdata(33 downto 0);
			ADDR(33 downto 32) <= treq_tdata(33 downto 32);--ADDR重定向
			if    (treq_tdata(31 downto 16)>=maping1_base and treq_tdata(31 downto 16)<=maping1_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping1_base&x"0000")+maping1_target;
            elsif (treq_tdata(31 downto 16)>=maping2_base and treq_tdata(31 downto 16)<=maping2_high) then
                ADDR(31 downto 0) <= treq_tdata(31 downto 0)-(maping2_base&x"0000")+maping2_target;
            else
                ADDR(31 downto 0) <= treq_tdata(31 downto 0);
            end if;
            DBINFO  <= treq_tdata(31 downto 16);
			TUSER	<= treq_tuser;
			regLast <= treq_tlast;	
		else
			TID		<= TID;
			FTYPE	<= FTYPE;
			TTYPE	<= TTYPE;
			SIZE	<= SIZE;
			ADDR	<= ADDR;
			DBINFO  <= DBINFO;
			TUSER	<= TUSER;
			regLast <= regLast;
		end if;
	end if; end process;

--sNrdRaxi延迟模块
	cntsNswrWA2axi_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sNswrWA2axi ) then
			cntsNswrWA2axi <= cntsNswrWA2axi + 1;
		else
			cntsNswrWA2axi <= x"0";
		end if;
	end if; end process;

--sNrdRaxi延迟模块
	cntsNrdRAaxi_logic: process(clk) begin
	if rising_edge(clk) then
		if ( state=sNrdRAaxi ) then
			cntsNrdRAaxi <= cntsNrdRAaxi + 1;
		else
			cntsNrdRAaxi <= x"0";
		end if;
	end if; end process;	
	
--RAM写地址选择模块
	cntTrans_logic: process(clk) begin
	if rising_edge(clk) then	
		if ( state=sNswrGetData ) then
			if (treq_tvalid='1' and treq_tready_w='1') then
				cntTrans <= cntTrans + 1;
			else
				cntTrans <= cntTrans;
			end if;
		elsif ( state=sNswrResp or state=sNswrWA2axi or state=sNswrWAwaitdone or state=sNswrFinish ) then
			cntTrans <= cntTrans;
		else
			cntTrans <= x"00";
		end if;
	end if;
	end process;
	
--回复数据包计数器模块:回复到了第几个数据包
	cntsNrdRespData_logic: process(clk) begin if rising_edge(clk) then
		if ( state=sNrdRespData and tresp_tvalid_w='1' and tresp_tready='1') then
			cntsNrdRespData <= cntsNrdRespData+1;
		elsif ( state=sNrdRAaxi or state=sNrdRAwaitdone or state=sNrdRespHead  ) then
			cntsNrdRespData <= x"00";
		else
			cntsNrdRespData <= cntsNrdRespData;
		end if;
	end if; end process;

end Behavioral;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值