【TREQRESP】部分修改方案及进步学习

文章描述了一个TREQRESP部分的修改方案,旨在当接收到特定数据帧如NRead、NWrite等时,不仅将数据写入双口RAM,还创建消息写入FIFO供用户读取或触发中断。用户可配置哪些数据帧类型敏感,信息包括地址、长度、源ID、目标ID和类型。此外,系统还扩展了双口RAM的消息存储功能,提供地址指针并支持指针清零。
摘要由CSDN通过智能技术生成

TREQRESP部分修改方案

修改要求

目前程序的处理方式是作为TARGET端接收到数据后,例如接收到NWrite、Swrite后把数据写入双口RAM中缓存,然后调用AXI总线DMA模块把数据直接搬移到内容中,并不形成中断,也没有给用户发消息,用户如果不读取数据的话则无法知道有这些数据帧发生。例如接收到Nread后,直接根据Nread帧中的地址调用AXI总线DMA模块把数据搬移到双口RAM缓冲中,然后通过Response回复包(包含TID信息)回复给远端节点。例如Doorbell(简称DB),模块接收到后自动回复一个门铃回复包,并把门铃帧相关的信息写入到FIFO中(数据/信息写入到FIFO中,用户就有办法获取到曾经发生了DB帧的这个事情了)。

我们要做的事情:

1)来了NRead、NWrite、NWrite_R、Swrite包,也形成一个消息写入到FIFO中,供用户后续读取,或者是触发中断后由用户读取;

需要保留给用户的信息有:(总共的数据宽度64bit)
数据发送的地址(保留原地址,32bit),长度(8bit),,源ID(16bit,是Tuser数据的【31:16】),目的ID(咱们只保留5bit存储,是Tuser数据的【4:0】)类型(3bit)

2)用户可以配置哪些信息保留,例如可以在这个模块上加一个input 8bit位宽的信号,每个bit对应一种数据帧类型,为0则表示敏感这种数据帧(即数据帧来了则形成一条记录消息写入到FIFO中),为1则不敏感。
3)扩展功能,上述消息可以写入到双口RAM中,给用户双口RAM的地址指针,例如双口RAM的大小为512个*64bit位宽,没增加一条消息,指针+1,同时也具备指针清零功能。

修改方法:

1.根据DBWrInfo判断在sGotHead和sNswrGeyData、sNrdRAaxi中间增加WrInfo状态写入information。
reglast=1和FTYPE=2
reglast=0和FTYPE=5或6
sGotHead 收获头帧
sNrdWrInfo 读状态信息写
SNrdRAaxi 读模式下Axi
SDBWrInfo DB写入FIFO数据
sNswrWrInfo 写状态数据写
SNswrGetData NWrite\SWrite模式得到数据
---@@@
		when sGotHead =>
			if ( regLast='1' ) then
				if ( FTYPE=x"2" ) then
					state <= sNrdWrInfo;
				elsif ( FTYPE=x"a" ) then
					state <= sDbWrInfo;
				else
					state <= sIdle;
				end if;
			else
				if ( FTYPE=x"5" or FTYPE=x"6" ) then
					state <= sNswrWrInfo;
				else
					state <= sIdle;
				end if;		
			end if;
---@@@
---@@@
		when sNswrWrInfo =>
			state <=sNswrGetData;
---@@@		
---@@@
		when sNrdWrInfo =>
			state<= sNrdRAaxi;
---@@@
2.解码部分添加对应数据信息

需要读出原地址,未经过更改偏移重映射的原地址;解析模式的类型(使用case语句判断)

--解析、地址重映射模块
	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';
			ADDR_pre<=x"00000000";
		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;
            ADDR_pre<=treq_tdata(31 downto 0);
            DBINFO  <= treq_tdata(31 downto 16);
			TUSER	<= treq_tuser;
			regLast <= treq_tlast;
			--@@@INT类型判断
			if(FTYPE=x"5" AND TTYPE=x"4") then
				INT_type <="000";-- NWRITE 类型:000				
			elsif(FTYPE=x"5" AND TTYPE=x"5") then
				INT_type <="001";--NWRITE_R 类型:001
			elsif(FTYPE=x"6" AND TTYPE=x"0") then
				INT_type<="010";--SWRITE 类型:010
			elsif(FTYPE=x"2" AND TTYPE=x"4") then
				INT_type<="011";--NREAD 类型:011
			else
				INT_type<=INT_type;
			end if;
			---@@@
		else
			TID		<= TID;
			FTYPE	<= FTYPE;
			TTYPE	<= TTYPE;
			SIZE	<= SIZE;
			ADDR	<= ADDR;
			DBINFO  <= DBINFO;
			TUSER	<= TUSER;
			regLast <= regLast;
		end if;
	end if; end process;

解析是在sWaitHead阶段进行,数据有一个周期的延迟,treq_data为实时数据。

 ADDR_pre<=treq_tdata(31 downto 0);

命令模式的判断:

命令格式类型
NWRITE000
NWRITE_R001
SWRITE010
NREAD011
--@@@INT类型判断
			if(FTYPE=x"5" AND TTYPE=x"4") then
				INT_type <="000";-- NWRITE 类型:000				
			elsif(FTYPE=x"5" AND TTYPE=x"5") then
				INT_type <="001";--NWRITE_R 类型:001
			elsif(FTYPE=x"6" AND TTYPE=x"0") then
				INT_type<="010";--SWRITE 类型:010
			elsif(FTYPE=x"2" AND TTYPE=x"4") then
				INT_type<="011";--NREAD 类型:011
			else
				INT_type<=INT_type;
			end if;
			---@@@
3.数据存入FIFO中
FIFO信息读取
---@@@ INT的FIFO控制逻辑
INT_fifo_logic:process(clk) begin if rising_edge(clk) then
	if( state=sNswrWrInfo or state=sNrdWrInfo) then
		case INT_type is
		when "000" =>
			INT_fifo_wren <=NOT INT_control(0);
		when "001":
			INT_fifo_wren <=NOT INT_control(1);
		when "010":
			INT_fifo_wren <=NOT INT_control(2);
		when "011":
			INT_fifo_wren <=NOT INT_control(3);
		when others:
			INT_fifo_wren <='0';
		end case;
		INT_fifo_data <= ADDR(31 downto 0) & SIZE & INT_type & TUSER(31 downto 16) & TUSER(4 downto 0);--ADDR 32bit SIZE 8bit INT_type 3bit TUSER 16bit TUSER 5bit
	else
		INT_fifo_wren <= '0';
		INT_fifo_data <= x"0000000000000000";
	end if;
	end if; end process;
4.控制是否敏感对应信号

用户可以配置哪些信息保留,例如可以在这个模块上加一个input 8bit位宽的信号,每个bit对应一种数据帧类型,为0则表示敏感这种数据帧(即数据帧来了则形成一条记录消息写入到FIFO中),为1则不敏感。

---@@@ INT的FIFO控制逻辑
INT_fifo_logic:process(clk) begin if rising_edge(clk) then
	if( state=sNswrWrInfo or state=sNrdWrInfo) then
		case INT_type is
		when "000" =>
			INT_fifo_wren <=NOT INT_control(0);
		when "001":
			INT_fifo_wren <=NOT INT_control(1);
		when "010":
			INT_fifo_wren <=NOT INT_control(2);
		when "011":
			INT_fifo_wren <=NOT INT_control(3);
		when others:
			INT_fifo_wren <='0';
		end case;
		INT_fifo_data <= ADDR(31 downto 0) & SIZE & INT_type & TUSER(31 downto 16) & TUSER(4 downto 0);--ADDR 32bit SIZE 8bit INT_type 3bit TUSER 16bit TUSER 5bit
	else
		INT_fifo_wren <= '0';
		INT_fifo_data <= x"0000000000000000";
	end if;
	end if; end process;
增加一个ram

扩展功能,上述消息可以写入到双口RAM中,给用户双口RAM的地址指针,例如双口RAM的大小为512个*64bit位宽,没增加一条消息,指针+1,同时也具备指针清零功能。

--@@@ INTERUPT RAM 写控制模块
	INT_ram_logic:process(clk) begin
	if rising_edge(clk) then
		case state is
		when sNrdWrInfo =>
			INT_WA_addr <=cnt_INT(8 downto 0);
			INT_WA_wren <= "1";
			INT_WA_data_wr<=ADDR_pre  & SIZE & TUSER(31 downto 16) & TUSER(4 downto 0) & INT_type;
		when sNswrWrInfo =>
			INT_WA_addr <=cnt_INT(8 downto 0);
			INT_WA_wren <= "1";
			INT_WA_data_wr<= ADDR_pre  & SIZE & TUSER(31 downto 16) & TUSER(4 downto 0) & INT_type;
		when others =>
			INT_WA_addr <=cnt_INT(8 downto 0);
			INT_WA_wren <="0";
			INT_WA_data_wr<=x"0000000000000000";
		end case;
	end if;
	end process;
	INT_RAM_cnt<=cnt_INT;
--@@@ INTERUPT CNT 
	INT_cnt_logic:process(clk) begin
	if rising_edge(clk) then	
		if ( INT_cnt_rst ='1') then
			cnt_INT<=x"00000000";
		elsif ( state=sNrdWrInfo or state=sNswrWrInfo) then
			cnt_INT <= cnt_INT+1;
		else
			cnt_INT <= cnt_INT;
		end if;
	end if;
	end process;

学习

重映射地址

	--Addr Remap-------------------------------
    signal maping1_base     : std_logic_vector(15 downto 0):=x"0006";
    signal maping1_high     : std_logic_vector(15 downto 0):=x"0017";
    signal maping1_target   : std_logic_vector(31 downto 0):=x"00500000";
    signal maping2_base     : std_logic_vector(15 downto 0):=x"0020";
    signal maping2_high     : std_logic_vector(15 downto 0):=x"0040";
    signal maping2_target   : std_logic_vector(31 downto 0):=x"00700000";   
	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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值