Модуль приемника USB (с сигналом сброса на некоторые регистры)
//simplest low speed USB receive functionmodule ls_usb_recv(input wire reset,//clock should be 12Mhz
input wire clk,//usb BUS signals
input wire dp,
input wire dm,
input wire enable,
output wire EOP,//output received bytes interface
output reg [7:0]rdata,
output reg rdata_ready,
output reg [3:0]rbyte_cnt,
output wire usb_reset
);//fix current USB line valuesreg[1:0]dp_input;reg[1:0]dm_input;always @(posedge clk) begin dp_input <={ dp_input[0], dp };
dm_input <={ dm_input[0], dm };end//if both lines in ZERO this is low speed EOP//EOP reinitializes receiverassign EOP = !(dp_input[0]| dp_input[1]| dm_input[0]| dm_input[1]);reg[3:0]eop_cnt;assign usb_reset =(eop_cnt==4'hF);always @(posedge clk) beginif(~EOP) eop_cnt <=4'h0;elseif( !usb_reset && strobe) eop_cnt <= eop_cnt +1'b1;end//change on DP line defines strobingwire dp_change;assign dp_change = dp_input[0]^ dp_input[1];//generate clocks with this counterreg[2:0]clk_counter;reg _strobe;reg strobe;//make strobe impulsealways @(posedge clk or posedge reset) beginif(reset) begin
clk_counter <=0;
_strobe <=0;endelsebegin//every edge on line resynchronizes receiver clockif(dp_change) begin
clk_counter <=0;
_strobe <= (clk_counter!=3'b000);endelse{ _strobe , clk_counter }<= clk_counter +1'b1;endendalways @(posedge clk) strobe <= _strobe;//next bit received is ONE if no signal change or ZERO if signal changedwire next_bit;assign next_bit =(last_fixed_dp == dp_input[1]);//calc number of sequental ONEs in received bit streamreg[2:0]num_ones;always @(posedge clk or posedge reset) beginif(reset) num_ones <=0;elseif(strobe & receiver_enabled) beginif(next_bit) num_ones <= num_ones +1'b1;else
num_ones <=0;endend//flag which mean that zero should be removed from bit streamwire do_remove_zero;assign do_remove_zero =(num_ones==6);reg[2:0]receiver_cnt;reg last_fixed_dp;reg receiver_enabled;//enable receiver on raising edge of DP linealways @(posedge clk or posedge EOP ) beginif(EOP) receiver_enabled <=1'b0;elseif( dp_input[0] ) receiver_enabled <=1'b1& enable;end//receiver processalways @(posedge clk or posedge EOP ) beginif(EOP) begin//kind of reset
receiver_cnt <=0;
rbyte_cnt <=0;
last_fixed_dp <=1'b0;
rdata <=0;
rdata_ready <=1'b0;endelsebeginif(strobe & receiver_enabled & (!do_remove_zero)) begin//decode NRZI//shift-in ONE if older and new values are same//shift-in ZERO if older and new values are different//BUT (bitstuffling) do not shift-in one ZERO after 6 ONEs
rdata <={ next_bit, rdata[7:1]};
receiver_cnt <= receiver_cnt +1'b1; end//set write-enable signal (write into receiver buffer)
rdata_ready <= (receiver_cnt ==7) & (strobe & receiver_enabled & (!do_remove_zero));//remember last fixed DP,if(strobe & receiver_enabled) last_fixed_dp <= dp_input[1];//count nomber of received bytesif(rdata_ready) rbyte_cnt <= rbyte_cnt +1'b1;endend
Подробнее...