// //this module allows USB CORE read predefined USB packets bytes // module pkt_reader( input wire reset, input wire clk, input wire [8:0]addr, input wire addr_wr, input wire addr_inc, //UFM addr control output wire ar_clk_ena, output wire ar_shift, output wire ar_out, //UFM data control input wire dr_in, output wire dr_shift, output wire ready, output reg [15:0]dr, //Altera CPLD UFM data has 16 bit, but we convert interface to 8 bits //result is 8-bit interface and packet byte ready flag and sign about last byte in packet output reg [7:0]pkt_byte, output reg pkt_byte_ready, output wire last_pkt_byte ); //count bits of UFM access (including address and data bits) reg [4:0]counter; always @(posedge clk) begin if(addr_wr) counter <= 0; else if(addr_inc & addr_odd) counter <= 5'd10; else if(counter<27) counter <= counter + 1'b1; end //when data read from UFM we set ready assign ready = (counter==5'd26); //UFM address is shifted out when early counting assign ar_shift = (counter < 5'd9); //UFM enable clock for address shifting and address auto-increment assign ar_clk_ena = ar_shift | (counter==5'd10); //define when we need to read next word from UFM wire need_next_word; assign need_next_word = addr_odd & addr_inc; //UFM address shift out register reg [8:0]addr_shift_reg; assign ar_out = addr_shift_reg[8]; reg addr_odd; reg first_pkt_byte; always @(posedge clk) begin if(addr_wr) begin addr_shift_reg <= addr; addr_odd <= 1'b0; end else begin addr_shift_reg <= {addr_shift_reg[7:0],1'b0}; if(addr_inc) addr_odd <= addr_odd ^ 1'b1; end end //return packet byte ready signal always @(posedge clk) pkt_byte_ready <= ready | (addr_inc & (~addr_odd)); //load length of packet from 1st byte read reg [3:0]pkt_num_bytes; always @(posedge clk) begin if(addr_wr) pkt_num_bytes <= 0; else //get number of bytes in packet from 1st read byte of packet //this 1st byte will be replaced by SYNC==8'h80 if( (pkt_num_bytes==0) & ready) pkt_num_bytes <= dr[3:0]; end //count bytes passed to core reg [3:0]bytes_cnt; always @(posedge clk) begin if(addr_wr) bytes_cnt <= 0; else if( pkt_byte_ready) bytes_cnt <= bytes_cnt + 1'b1; end //decide about last byte in packet if length read from 1st byte is equal to num bytes already passed assign last_pkt_byte = (bytes_cnt == pkt_num_bytes) & (|pkt_num_bytes); //shift in UFM data assign dr_shift = (counter>5'd9) && (counter<5'd26); always @(posedge clk) begin if(dr_shift) dr <= {dr[14:0],dr_in}; end always @* begin if(bytes_cnt==0 || bytes_cnt==1) pkt_byte[3:0] = 4'h0; else if(addr_odd) pkt_byte[3:0] = dr[11:8]; else pkt_byte[3:0] = dr[3:0]; end always @* begin if(addr_odd) pkt_byte[7:4] = dr[15:12]; else pkt_byte[7:4] = dr[7:4]; end endmodule
Подробнее...