?? translatetoutopia.vhd
字號:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TranslateToUTOPIA is -- slave mode
generic(
fifo_width: integer := 32;
Pclass : integer := 4;
clock_syn : boolean := true
);
Port (
reset : in std_logic;
txclk : in std_logic;
sysclk : in std_logic;
txaddr : in std_logic_vector(4 downto 0);
txenb : in std_logic;
txclav : out std_logic;
txclaven : out std_logic;
txdata : out std_logic_vector(7 downto 0);
txdataen : out std_logic;
txsoc : out std_logic;
txsocen : out std_logic;
rbe : in std_logic_vector(Pclass - 1 downto 0);
rdd : in std_logic_vector(fifo_width - 1 downto 0);
rdeop : out std_logic;
rden : out std_logic;
rdport : out std_logic_vector(Pclass - 1 downto 0);
timerset : in std_logic_vector((Pclass * 16) - 1 downto 0);
phyaddr : in std_logic_vector(4 downto 0)
);
end TranslateToUTOPIA;
architecture Behavioral of TranslateToUTOPIA 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;
type translatestate is (idle,waiting,translating,stop,pause,pause1,pause2);
signal state : translatestate;
signal dataout : std_logic_vector(7 downto 0);
signal offset : integer range 0 to 63 :=0;
signal crc8 : std_logic_vector(7 downto 0);
signal rden_tmp : std_logic;
signal rdeop_tmp : std_logic;
signal txclk_d : std_logic;
signal txclken : std_logic;
signal clk,clk_en : std_logic;
signal txenb_syn : std_logic;
signal txaddr_tmp : std_logic_vector(4 downto 0);
signal txclav_tmp : std_logic;
signal txdata_tmp : std_logic_vector(7 downto 0);
signal txdataen_tmp : std_logic;
signal txsoc_tmp : std_logic;
signal txsocen_tmp : std_logic;
signal temp : std_logic_vector(31 downto 0);
signal txrbe : std_logic;
type timertype is array(Pclass -1 downto 0) of std_logic_vector(15 downto 0);
signal timer : timertype;
signal txenable : std_logic_vector(Pclass -1 downto 0):=(others=>'0');
signal rdport_tmp : std_logic_vector(Pclass - 1 downto 0);
begin
txrbeProc : Process(rbe)
variable temp : std_logic;
begin
temp := '1';
for i in 0 to Pclass - 1 loop
temp := temp and rbe(i);
end loop;
txrbe <= temp;
end Process;
in_syn_proc : process(txclk)
begin
if txclk'event and txclk = '1' then
txenb_syn <= txenb;
if txenb = '1' then
txaddr_tmp <= txaddr;
end if;
end if;
end process;
txclav_tmp_Proc : process(txclk)
begin
if txclk'event and txclk = '1' then
if txaddr = phyaddr then
txclaven <= '1';
else
txclaven <= '0';
end if;
end if;
end process;
label1 : if clock_syn /= true generate
begin
clk <= txclk;
clk_en <= '1';
txdata <= txdata_tmp;
txdataen <= txdataen_tmp;
txclav <= txclav_tmp;
txsoc <= txsoc_tmp;
txsocen <= txsocen_tmp;
txdata_tmp <= crc8 when offset = 4 else dataout;
txdataen_tmp <= not txenb_syn when (txaddr_tmp = phyaddr) and (state /= idle) else '0';
rden <= rden_tmp;
rdeop <= rdeop_tmp;
rdport <= rdport_tmp;
end generate;
label2 : if clock_syn = true generate
begin
clk <= sysclk;
clk_en <= txclken;
txdata_tmp <= crc8 when offset = 4 else dataout;
txdataen_tmp <= not txenb_syn when (txaddr_tmp = phyaddr) and (state /= idle) else '0';
data_syn_proc : process(txclk)
begin
if txclk'event and txclk = '1' then
txdata <= txdata_tmp;
txdataen <= txdataen_tmp;
txclav <= txclav_tmp;
txsoc <= txsoc_tmp;
txsocen <= txsocen_tmp;
end if;
end process;
txclk_syn_proc : process(txclk,txclken)
begin
if (txclken or reset) = '1' then
txclk_d <= '0';
elsif txclk'event and txclk = '1' then
txclk_d <= '1';
end if;
end process;
rxclkce_proc : process(sysclk)
begin
if sysclk'event and sysclk = '1' then
txclken <= txclk_d;
end if;
end process;
rd_proc : process(sysclk)
begin
if sysclk'event and sysclk = '1' then
rden <= rden_tmp and txclken;
rdeop <= rdeop_tmp and txclken;
rdport <= rdport_tmp;
end if;
end process;
end generate;
stateProc : process(clk)
begin
if clk'event and clk = '1' then
if reset = '1' then
state <= idle;
rdeop_tmp <= '0';
txclav_tmp <= '0';
txsoc_tmp <= '0';
txsocen_tmp <= '0';
rden_tmp <= '0';
offset <= 0;
temp <= (others=>'0');
crc8 <= (others=>'0');
for i in 0 to Pclass - 1 loop
timer(i) <= (others=>'0');
txenable(i) <= '1';
rdport_tmp(i) <= '0';
end loop;
elsif clk_en = '1' then
for i in 0 to Pclass - 1 loop
if (txenable(i)and not rbe(i)) = '1' then
timer(i) <= timerset((16 * i) + 15 downto 16 * i);
else
if timer(i) /= x"0000" then
timer(i) <= timer(i) - 1;
end if;
end if;
if timer(i) = x"0000" then
txenable(i) <= '1';
else
txenable(i) <= '0';
end if;
end loop;
case state is
when idle =>
rdeop_tmp <= '0';
rden_tmp <= '0';
offset <= 0;
for i in 0 to Pclass - 1 loop
if (txenable(i) and not rbe(i)) = '1' then
state <= waiting;
rdport_tmp(i) <= '1';
exit;
else
rdport_tmp(i) <= '0';
end if;
end loop;
when waiting =>
if (txaddr_tmp = phyaddr) and (txenb_syn = '0') then
txsoc_tmp <= '1';
txsocen_tmp <= '1';
temp <= rdd;
rden_tmp <= '1';
state <= translating;
else
txsoc_tmp <= '0';
txsocen_tmp <= '0';
end if;
offset <= 0;
txclav_tmp <= '1';
crc8 <= (others=>'0');
when translating =>
txclav_tmp <= '0';
txsoc_tmp <= '0';
txsocen_tmp <= '0';
if clock_syn = true then
if (((offset mod 4) = 3) and (offset > 4)) or ( offset = 4) then
rden_tmp <= '1';
temp <= rdd;
else
rden_tmp <= '0';
end if;
else
if ((offset mod 4) = 3) or (offset = 4) then
temp <= rdd;
end if;
if ((offset mod 4) = 2) then
rden_tmp <= '1';
else
rden_tmp <= '0';
end if;
end if;
if offset = 4 then
offset <= 8;
else
offset <= offset + 1;
end if;
if offset < 4 then
CRC8 <= Get_CRC(dataout,CRC8,x"35");
end if;
if txenb_syn = '1' then
state <= stop;
end if;
when stop =>
rden_tmp <= '1';
rdeop_tmp <= '1';
state <= pause;
when pause =>
rdeop_tmp <= '0';
rden_tmp <= '0';
state <= pause1;
when pause1 =>
state <= pause2;
for i in 0 to Pclass - 1 loop
rdport_tmp(i)<= '0';
end loop;
when pause2 =>
state <= idle;
when others =>
state <= idle;
end case;
end if;
end if;
end process;
dataout_Proc : process(offset,temp)
begin
case offset mod 4 is
when 0 =>
dataout <= temp(31 downto 24);
when 1 =>
dataout <= temp(23 downto 16);
when 2 =>
dataout <= temp(15 downto 8);
when others =>
dataout <= temp(7 downto 0);
end case;
end process;
end Behavioral;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -