TREQRESP部分修改方案
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。
---@@@
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);
命令模式的判断:
命令格式 | 类型 |
---|---|
NWRITE | 000 |
NWRITE_R | 001 |
SWRITE | 010 |
NREAD | 011 |
--@@@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;