architecture arch_of_mem_arb of usbf_mem_arb is
signal wsel:std_logic;
signal mcy:stdlogic;
signal wack_r:std_logic;
begin
wsel<=(wreq or wack)and not(mreq);
--对SRAM数据输出
process(wsel,wdin,mdin)
begin
if(wsel='1')then
sram_dout<=wdin;
else sram_dout<=mdin;
end if;
end process;
--sram地址线输出
process(wsel,wadr,madr)
begin
if(wsel='1')then
sram_adr<=wadr;
else sram_adr<=madr;
end if;
end process;
--sram写操作使能控制
process(wsel,wwe,wreq,mwe,mcyc)begin
if(wsel='1')then
sram_we<=wreq and wwe;
else sram_we<=mwe and mcc;
end if;
end process;
sram_re<='1';
mdout<=sram_din;
mack<=mreq;
mcyc<=mack;
--应用模块之间的wishbone接口
wdout<=sram_din;
wack<=wack_r and not(mreq);
process(rst,phy_clk)begin
if(rst='0')then
wack_r<='0';
else if(ph_clk' event and phy_clk='1')then
wack_r<=wreq and not(mreq)and not(wack);
end if;
end process;
end architecture;
signal state,next_state:std_logic_vector(5 downto 0);
signal wb_req_sl:std_logic;
signal wb_ack_d,wb_ack_sl,wb_ack_sla,wb_ack_s2:std_logic;
signal rf_we_d:std_logic;
--状态机状态
begin
ma_adr<=wb_addr_i;
ma_dout<=wb_data_i;
rf_dout<=wb_data_i;
--数据,地址由应用模块驱动,输出至存储器或内部存储器
process(wb_clk)begin
if(wb_clk'evevt and wb_clk='1')then
if(not(wb_addr_i(17)0='1')then
wb_data_o<=rf_din;
else wb_data_o<=ma_din;
end if;
end if;
end process;
--数据通道,仲裁数据输入来源是寄存器或储存器
process(phy_clk)begin
if phy_clk'event and phy_clk='1'then
wb_req_s1<=(wb_std_i nd wb_cyc_i);
end if;
end process;
--wishbone 请求
process(wb_clk)begin
if wb_clk'event and wb_clk='1' then
wb_ack_sl<=wb_ack_d;
end if;
end process;
process(wb_clk)begin
if wb_clk'event and wb_clk='1' then
wb_ack_o<=(wb_ack_s1 and not(wb_ack_s2)and not(wb_ack_0));
end if;
end process;
process(wb_clk)begin
if wb_clk'event and wb_clk='1' then
wb_ack_s2<=wb_ack_s1a;
end if;
end process;
process(wb_clk)begin
if wb_clk'event and wb_clk='1' then
wb_ck_s2<=wb_ack_s1a;
end if;
end process;
--内部寄存器写使能驱动
rf_we<=rf_we_d;
process(phy_clk,rst)begin
if(rst='0')then
state<=IDLE;
elsif wb_clk'event and wb_clk='1' then
state<=next_state;
end if;
end process;
process(state,wb_req_s1,wb_addr_i,ma_ack,wb_we_i)
begin
next_state<=state;
ma_req<='0';
ma_we<='0';
wb_ack_d<='0';
rf_re<='0';
rf_we_d<='0';
case state is --状态机状态转移
when IDLE=>
if(wb_req_s1='1' and wb_addr_i(17)='0'and wb_we_i='1')then
ma_req<='1';
ma_we<='1';
next_state<=M_WR; --存储器写状态
end if;
if(wb_req_s1='1' and wb_addr_i(17)='0'and wb_we_i='0')then
ma_req<='1';
next_state<=MA_WR; --存储器读状态
end if;
if(wb_req_s1='1' and wb_addr_i(12)='0'and wb_we_i='1')then
rf_we_d<='1';
next_state<=W0; --寄存器写状态
end if;
if(wb_req_s1='1' and wb_addr_i(12)='0'and wb_we_i='0')then
rf_re<='1';
next_state<=W0; --寄存器读状态
end if;
when MA_WR=>
if(ma_ack='0')then
ma_req<='1';
ma_we<='1';
else
wb_ack_d<='1';
next_state<=W1;
end if;
when MA_RD=>
if(ma_ack='0') then
ma_req<='1';
else
wb_ack_d<='1';
next_state<=W1;
end if;
signal pid:std_logic_vector(7 downto 0); --PDI
signal pid_le_sm:std_logic; --状态机pid有效
signal pid_ld_en:std_logic; --pid有效使能
signal pid_RES:std_logic;
signal pid_TOKEN:std_logic; --所有的令牌包统一的信号
signal pid_DATA:std_logic; --所有的数据包统一信号
signal token0,token1:std_logic_vector(7 downto 0); --令牌包缓存
signal token_le_1,token_le_2:std_logic; --令牌包缓存有效使能
signal token_crc5:std_logic_vector(4 downto 0);
signal d0,d1,d2:std_logic_vector(7 downto 0); --数据通道延迟线(计算CRC5)
signal data_valid_d:std_logic; --状态机输出数据有效信号
signal data_done:std_logic; --数据有效信号延迟
signal rxv1:std_logic;
signal rxv2:std_logic;
signal got_pid_ack:std_logic;
signal token_valid_r1:std_logic;
signal token_valid_str1:std_logic;
signal rx_active_r:std_logic; --输出有效
signal crc5_out:std_logic_vector(4 doento 0);
signal crc5_out2:std_logic_vector(4 doento 0);
signal crc16_clr:std_logic;
signal crc16_sum:std_logic_vector(15 down 0);
signal crc16_out:std_logic_vector(15 down 0); --crc5 crc16校验
signal rx_data_temp:std_logic_vector(7 downto 0);
signal token_temp:std_logic_vector(10 downto 0);
begin
--PID逻辑分析
pid_ld_en<=pid_le_sm and rx_active and rx_valid;
--PID输入寄存
process(clk,rst)begin
if(rst='0')then
pid<="11110000";
elsif clk'event and clk='1'then
if(pid_ld_en='1')then
pdi<=rx_data;
end if;
end if;
end process;
--PID校验,识别
process(pid)begin
if pid(3 downto 0)/=not(pid(7 downto 4))then pid_cks_err<='1';
else pid_cks_err<='0';
end if; --PID校验
if pid(3 downto 0)=USBF_T_PID_OUT then pid_out<="1';
else pid_OUT<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_IN then pid_IN<='1';
else PID_SETUP<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_SOF then pid_SOF<='1';
else PID_SOF<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_SETUP then pid_setup<='1';
else PID_SETUP<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_DATA0 then pid_DATA0<='1';
else PID_DATA0<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_DATA1 then pid_DATA<='1';
else PID_DATA1<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_DATA2 then pid_DATA2<='1';
else PID_DATA2<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_MDATA then pid_MDATA<='1';
else PID_MDATA<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_ACK then pid_ACK<='1';
else PID_ACK<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_NACK then pid_NACK<='1';
else PID_NACK<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_STALL then pid_STALL<='1';
else PID_STALL<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_NYET then pid_NYET<='1';
else PID_NYET<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_PRE then pid_PRE<='1';
else PID_PRE<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_ERR then pid_ERR<='1';
else PID_ERR<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_SPLIT then pid_SPLIT<='1';
else PID_SPLIT<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_PING then pid_PING<='1';
else PID_PING<='0';
end if;
if pid(3 downto 0)=USBF_T_PID_RES then pid_RES<='1';
else PID_ACK<='0';
end if;
end process
--令牌包数据包的统一识别
pid_TOKEN<=pid_OUT or pid_SOF or pid_SRTUP or pid_PING;
pid_DATA<=pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA;
--令牌包分析模块
process(clk)begin
if clk'event and clk='1'then
if(token_le_1='1')then
token0<=rx_data;
end if;
end if
end process;
process(clk)begin
if clk'event and clk='1'then
if(token_le_2='1')then
token1<=rx_data;
end if;
end if
end process;
process(clk)begin
if clk'event and clk='1'then
token_valid_r1<=token_le_2;
end if
end process;
--数据接收逻辑
--rxv1 rxv2的作用是对数据有效信号做2个时钟的延迟
process(clk,rst)begin
if(rst='0') then
rxv1<='0';
elsif clk'event and clk='1'then
if(data_valid_d='1')then
rxv1<='1';
elsif(data_done='1')then
rxv1<='0';
end if;
end if;
end process;
process(clk,rst)begin
if(rst='0') then
rxv2<='0';
elsif clk'event and clk='1'then
if(rxv1='1' and data_valid_d='1')then
rxv2<='1';
elsif(data_done='1')then
rxv2<='0';
end if;
end if;
end process;
process(clk)begin
if clk'event and clk='1'then
data_valid0<=rxv2 and data_valid_d;
end if;
end process;
process(clk)begin
if clk'event and clk='1'then
if(data_valid_d='1')then d0<=rx_data;end if;
if(data_valid_d='1')then d1<=d0;end if;
if(data_valid_d='1')then d2<=d1;end if; --数据2个时钟延迟
end if;
end process;
--crc16数据校验
process(clk)begin
if clk'event and clk='1'then
rx_active_r<=rx_active;
end if;
end process;
crc16_clr<=rx_active and not(rx_active_r);
process(clk)begin
if clk'event and clk='1'then
if(crc16_clr='1')then
crc16_sum<='1111111111111111";
else
if(data_valid_d='1')then crc16_sum<=crc16_out;
end if;
end if;
end if;
end process;
rx_data_temp<=rx_data(0)&rx_data(1)&rx_data(2)&rx_data(3)
&rx_data(4)&rx_data(5)&rx_data(6)&rx_data(7);
usbf_crc16_u1:usb_crc16 port map(
crc16_sum,
rx_data_temp,
crc16_out
);
process(data_done,crc16_sum)begin
if crc16_sum/="1000000000001101"then
crc16_err<=data_done;
else crc16_err<='0';
end if;
end process;
--状态机设计
process(clk,rst)begin
if(rst='0') then
state<=IDLE;
elseif clk'event and clk='1'then
state<=next_state;
end if;
end process;
process(state,rx_valid,rx_active,rx_err,pid_ACK,pid_TOKEN,pid_DATA)
begin
next_state<=state; --默认状态不改变状态机状态
pid_le_sm<='0';
token_le_1<='0';
token_le_2<='0';
data_valid_d<='0';
data_done<='0';
seq_err<='0';
got_pid_ack<='0';
case state is ---状态机
when IDLE=>
pid_le_sm<='1';
if(rx_valid='1' and rx_active='1')then
next_state<=ACTIVE;
end if;
when ACTIVE=>
--收到数据包标识符号
if(pid_ACK='1' and rx_err='0')then
got_pid_ack<='1';
if(rx_active='0')then
next_atate<=IDLE;
end if;
--收到令牌token数据包标识符
elsif(pid_TOKEN='1' and rx_valid='1' and rx_ctive='1' and rx_err='0')then
token_le_1<='1';
next_state<=TOKEN;
--收到data数据包标识符
elsif(pid_TOKEN='1' and rx_valid='1' and rx_ctive='1' and rx_err='0')then
data_valid_d<='1';
next_state<=DATA;
elsif(rx_active='0' or rx_err='1'or
(rx_valid='1' and not(pid_TOKEN='1' or pid_DATA='1')))then
seq_err<==not(rx_err);
if(rx_active='0')then next_state<=IDLE;
end if;
end if;
--令牌token数据包处理
when TOKEN=>
if(rx_valid='1' and rx_active='1' and rx_err='0')then
token_le_2<='1';
next_state<=IDLE;
elsif(rx_active='0' or rx_err='1')then
seq_err<=not(rx_err);
if(rx_active='0')then
next_state<=IDLE;
end if;
end if;
--DATA数据包处理
when DATA=>
if(rx_valid='1' and rx_active='1' and rx_err='0') then
data_vlid_d<='1';
end if;
if(rx_active='0' or rx_err='1')then
data_done<='1';
if(rx_active='0')then
next_state<=IDLE;
end if;
end if;
when other=>
null;
end case;
end process;
end architecture;