📄 receivefromutopia.vhd
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ReceiveFromUTOPIA is -- slave mode
generic (
fifo_width : integer := 32;
clock_syn : boolean := true
);
Port (
reset : in std_logic;
rxclk : in std_logic;
sysclk : in std_logic;
rxdata : in std_logic_vector(7 downto 0);
rxenb : in std_logic;
rxsoc : in std_logic;
rxclav : out std_logic;
rxclaven : out std_logic;
rxaddr : in std_logic_vector(4 downto 0);
wbf : in std_logic;
wren : out std_logic;
wrsop : out std_logic;
wreop : out std_logic;
wrd : out std_logic_vector(31 downto 0);
phyaddr : in std_logic_vector(4 downto 0);
cha : in std_logic_vector(7 downto 0)
);
end ReceiveFromUTOPIA;
architecture Behavioral of ReceiveFromUTOPIA is
function Get_CRC(
data : std_logic_vector;
CRC : std_logic_vector;
CRC_ACCUM : std_logic_vector
)return std_logic_vector is
variable NewCRC : std_logic_vector(CRC'length - 1 downto 0);
variable OldCRC : std_logic_vector(CRC'length - 1 downto 0);
variable CRC_POLY : std_logic_vector(CRC'length - 1 downto 0);
begin
OldCRC := CRC;
CRC_POLY := CRC_ACCUM;
for i in data'length - 1 downto 0 loop
for j in 0 to CRC_POLY'length - 1 loop
if j = 0 then
if CRC_POLY(j) = '1' then
NewCRC(j) := OldCRC(CRC_POLY'length - 1) xor data(i);
else
NewCRC(j) := data(i);
end if;
else
if CRC_POLY(j) = '1' then
NewCRC(j) := OldCRC(CRC_POLY'length - 1) xor data(i) xor OldCRC(j - 1);
else
NewCRC(j) := OldCRC(j - 1);
end if;
end if;
end loop;
OldCRC := NewCRC;
end loop;
return NewCRC;
end Get_CRC;
signal rxaddr_tmp : std_logic_vector(4 downto 0);
signal rxdata_syn : std_logic_vector(7 downto 0);
signal rxenb_syn : std_logic;
signal rxsoc_syn : std_logic;
signal rxclav_tmp : std_logic;
signal rxclk_d : std_logic;
signal rxclken : std_logic;
signal clk,clk_en : std_logic;
signal wren_tmp : std_logic;
signal wrsop_tmp : std_logic;
signal wreop_tmp : std_logic;
signal VPIVCI : std_logic_vector(23 downto 0);
signal PT : std_logic_vector(3 downto 0);
signal offset : integer range 0 to 63 :=0;
signal rxd : std_logic_vector(31 downto 0);
signal Receiving : std_logic;
type translatestate is (idle,Receive,stop);
signal state : translatestate;
begin
inputSyn : process(rxclk)
begin
if rxclk'event and rxclk = '1' then
if rxenb = '1' then
rxaddr_tmp <= rxaddr;
end if;
end if;
end process;
rxclavProc : process(rxclk)
begin
if reset = '1' then
rxclav_tmp <= '0';
elsif rxclk'event and rxclk = '1' then
rxclav_tmp <= (not wbf) and not Receiving;
end if;
end process;
rxclaven_proc : process(rxclk)
begin
if rxclk'event and rxclk = '1' then
if (rxaddr = phyaddr) then
rxclaven <= '1';
else
rxclaven <= '0';
end if;
end if;
end process;
label1 : if clock_syn /= true generate
begin
clk <= rxclk;
clk_en <= '1';
rxdata_syn <= rxdata;
rxenb_syn <= rxenb;
rxsoc_syn <= rxsoc;
rxclav <= rxclav_tmp;
end generate;
label2 : if clock_syn = true generate
begin
clk <= sysclk;
clk_en <= rxclken;
rxclav <= rxclav_tmp;
data_syn_proc : process(rxclk)
begin
if rxclk'event and rxclk = '1' then
rxdata_syn<= rxdata;
rxenb_syn <= rxenb;
rxsoc_syn <= rxsoc;
end if;
end process;
rxclk_syn_proc : process(rxclk,rxclken)
begin
if (rxclken or reset) = '1' then
rxclk_d <= '0';
elsif rxclk'event and rxclk = '1' then
rxclk_d <= '1';
end if;
end process;
rxclkce_proc : process(sysclk)
begin
if sysclk'event and sysclk = '1' then
rxclken <= rxclk_d;
end if;
end process;
end generate;
data_out_proc : Process(clk)
begin
if clk'event and clk = '1' then
if reset = '1' then
wrd <= (others=>'0');
elsif state = Receive then
case offset is
when 8 =>
wrd <= x"0003" & cha & x"ff";
when 9 =>
wrd <= x"0300" & x"0030";
when 10 =>
wrd <= "0000" & VPIVCI & PT;
when 11 =>
when others =>
wrd <= rxd;
end case;
else
wrd <= rxd;
end if;
if clock_syn /= true then
wren <= wren_tmp;
wrsop <= wrsop_tmp;
wreop <= wreop_tmp;
else
wren <= wren_tmp and rxclken;
wrsop <= wrsop_tmp and rxclken;
wreop <= wreop_tmp and rxclken;
end if;
end if;
end Process;
stateProc : process(clk)
begin
if clk'event and clk = '1' then
if reset = '1' then
wreop_tmp <= '0';
wrsop_tmp <= '0';
wren_tmp <= '0';
offset <= 0;
Receiving <= '0';
state <= idle;
VPIVCI <= (others=>'0');
PT <= (others=>'0');
rxd <= (others=>'0');
elsif clk_en = '1' then
rxd <= rxd(23 downto 0) & rxdata_syn;
case state is
when idle =>
wreop_tmp <= '0';
wrsop_tmp <= '0';
wren_tmp <= '0';
if (rxaddr_tmp = phyaddr) and (rxenb_syn = '0') then
if rxsoc_syn = '1' then
offset <= 1;
end if;
Receiving <= '1';
state <= Receive;
else
offset <= 0;
Receiving <= '0';
end if;
when Receive =>
if rxenb_syn = '0' then
if rxsoc_syn = '1' then
offset <= 1;
else
if offset = 4 then
offset <= 8;
else
if offset = 55 then
offset <= 0;
else
offset <= offset + 1;
end if;
end if;
end if;
if offset = 4 then
VPIVCI <= rxd(27 downto 4 );
PT <= rxd(3 downto 0);
end if;
if ((offset mod 4) = 3 and (offset > 4)) or ((offset >= 4) and (offset < 12)) then
wren_tmp <= '1';
else
wren_tmp <= '0';
end if;
if offset = 55 then
wreop_tmp <= '1';
state <= stop;
else
wreop_tmp <= '0';
end if;
else
wren_tmp <= '0';
end if;
when stop =>
wren_tmp <= '0';
wreop_tmp <= '0';
if offset = 3 then
Receiving <= '0';
state <= idle;
else
offset <= offset + 1;
end if;
when others =>
state <= idle;
end case;
end if;
end if;
end process;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -