📄 usb_new_rcv_ram_rtl.vhdl
字号:
end if;
-- Flag will set only for ISO
if(IsoEndPoint) then
if(RxWrBufferNo = 6) then
RxValidData(0) <= true;
else
RxValidData(1) <= true;
end if;
end if;
if(RxError) then
RxError := false;
DataToRam(31) := '0';
else
DataToRam(31) := '1';
end if;
RxRamWriteData(DataToRam);
end RxRamWriteHeader;
-------------------------------------------------------------------------------
-- This procedure wirtes the data word into the RAM
procedure write_data_word is
begin
if(not RAM_WriteReq and BufferFree) then
DataToRam := MemBufReg(3) & MemBufReg(2) & MemBufReg(1) & MemBufReg(0);
RxRamWriteData(DataToRam);
ByteCount <= 0;
MemBufRegFull := false;
else
MemBufRegFull := true;
end if;
end write_data_word;
------------------------------------------------------------------------------
-- This function returns the index of buffer in RAM (RxRdBufferNo)
-- corresponding to a physical endpoint. The buffer allocation for different
-- endpoints is already desribed in procedure get_wr_buffer_index
procedure get_rd_buffer_index(Logical_EP: in logical_ep_type) is
variable Physical_EP: Int_EndPointType;
begin
Physical_EP := logical_to_physical(Logical_EP,'0');
case Logical_EP is
when 0 =>
RxRdBufferNo := 0;
when 1 =>
RxRdBufferNo := 1;
when 2 =>
if(UCToggleBuffer_Out(Physical_EP) = 0 and FullBuffer_EP(Physical_EP)(0)) then
RxRdBufferNo := 2;
elsif(UCToggleBuffer_Out(Physical_EP) = 1 and FullBuffer_EP(Physical_EP)(1)) then
RxRdBufferNo := 3;
end if;
when 3 =>
if(UCToggleBuffer_Out(Physical_EP) = 0 and FullBuffer_EP(Physical_EP)(0)) then
RxRdBufferNo := 4;
elsif(UCToggleBuffer_Out(Physical_EP) = 1 and FullBuffer_EP(Physical_EP)(1)) then
RxRdBufferNo := 5;
end if;
when 4 =>
if(PI_IsoToggle_Out = 1 and RxValidData(0)) then
RxRdBufferNo := 6;
elsif(PI_IsoToggle_Out = 0 and RxValidData(1)) then
RxRdBufferNo := 7;
else
EmptyBuffer := true;
end if;
end case;
end get_rd_buffer_index;
------------------------------------------------------------------------------
-- This procedure puts the address on RAM address bus and increments the
-- address pointer.
procedure RxReadRamData is
begin
RamAddress_Rd <= to_unsigned(RxRdAdPointer, RxRAMAddr_Width);
if(RxRdAdPointer = RxRamDepth - 1) then
RxRdAdPointer := 0;
else
RxRdAdPointer := RxRdAdPointer + 1;
end if;
end RxReadRamData;
------------------------------------------------------------------------------
-- This procedure manages the reading of RAM buffer corresponding to an endpoint
-- by putting the start address initially. If there was no packet in the last
-- frame from USB, then transfer an empty packet to system.
procedure RxRamReadManager is
begin
if(RxRdAdPointer = 0) then
get_rd_buffer_index(Endpoint_Nr);
write_pkt_length_I <= true;
if(not EmptyBuffer) then
RxRdAdPointer := get_rx_buffer_address(RxRdBufferNo);
RxReadRamData;
else
EmptyPacket <= '1';
end if;
else
RxReadRamData;
end if;
end RxRamReadManager;
------------------------------------------------------------------------------
begin
if(clk'event and clk = '1') then
-- synchronous reset to all registers
if(pvci_reset_n = '0') then
RxDataCount <= 0;
RxWrAdPointer := 0;
RxRdAdPointer := 0;
WriteRxHeader := false;
RAMAddress_Wr <= (others => '0');
RAMAddress_Rd <= (others => '0');
RxValidData <= (others => false);
RAM_WriteReq <= false;
RAMData <= (others => '0');
RxDataAccepted_I <= false;
RxWrBufferNo := 0;
RxRdBufferNo := 0;
BufferFree := false;
RxError := false;
ByteCount <= 0;
MemBufReg <= (others => (others =>'0'));
MemBufRegFull := false;
IsoEndpoint := false;
EmptyBuffer := false;
EmptyPacket <= '0';
write_pkt_length_I <= false;
else
-- RAM write logic
-- After collecting 4 bytes into memory buffer register, write into RAM
if(ByteCount = 4) then
write_data_word;
end if;
-- Start collecting bytes into memory buffer register
if(If_Busy and not(RxDataAccepted_I) and not(WriteRxHeader) ) then
RxRamManager;
end if;
if(RxDataAccepted_I) then
RxDataAccepted_I <= false;
end if;
if(RAM_WriteGrant) then
RAM_WriteReq <= false;
end if;
if(End_Transfer_D = '1' and BufferFree)then
WriteRxHeader := true;
end if;
if(RxError_Out and BufferFree) then
RxError := true;
end if;
IsoEndPoint := dma_endp_iso(EP_number_out);
-- Set flag for writing header into RAM
if(WriteRxHeader) then
if(not IsoEndPoint and ByteCount > 2)then
write_data_word;
elsif(IsoEndPoint and ByteCount > 0) then
write_data_word;
--if(ByteCount > 2) then
-- write_data_word;
else
RxRamWriteHeader;
BufferFree := false;
WriteRxHeader := false;
ByteCount <= 0;
end if;
end if;
-- RAM read logic
if(RxRam_Read = '1') then
RxRamReadManager;
end if;
if(Rx_Pkt_End = '1') then
RxRdAdPointer := 0;
if(RxRdBufferNo = 6) then
RxValidData(0) <= false;
elsif(RxRdBufferNo = 7) then
RxValidData(1) <= false;
end if;
end if;
if(EmptyPacket = '1') then
EmptyPacket <= '0';
EmptyBuffer := false;
end if;
--RamAddress_Rd <= to_unsigned(RxRdAdPointer, RxRAMAddr_Width);
if(write_pkt_length_I) then
write_pkt_length_I <= false;
end if;
end if; -- end of reset if
end if; -- end of clock if
end process;
-- RAM arbitrer between RAM writing by RAM_MANAGER and reading by USB_CONTROLLER
-- RAM_MANGAER has the higher priority
RAM_WriteGrant <= RAM_WriteReq and (RxRam_Read = '0');
RAMAddress <= RAMAddress_Wr when RAM_WriteGrant else RAMAddress_Rd;
Write <= '1' when RAM_WriteGrant else '0';
RxRAM_A <= RAMAddress;
RxRAM_W_N <= Not(Write);
RxRAM_G_N <= Not(clk);
RxRAM_DQ_Out <= RAMData;
DataFromRam <= RxRAM_DQ_In when (EmptyPacket = '0') else (others => '0');
RxRAM_E_N <= pvci_reset_n;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -