mirror of
https://github.com/UzixLS/zx-sizif-xxs.git
synced 2025-07-19 07:11:28 +03:00
fpga: remove unused usbhost files
This commit is contained in:
@ -1,383 +0,0 @@
|
||||
|
||||
//simplest low speed USB CORE function
|
||||
|
||||
module ls_usb_core(
|
||||
|
||||
//clock should be 5Mhz
|
||||
input wire clk,
|
||||
|
||||
input wire EOP,
|
||||
input wire [7:0]data,
|
||||
input wire wre,
|
||||
|
||||
input wire [3:0]rbyte_cnt,
|
||||
|
||||
input wire show_next,
|
||||
|
||||
output reg [7:0]sbyte,
|
||||
output reg start_pkt,
|
||||
output reg last_pkt_byte,
|
||||
output reg [7:0]leds
|
||||
);
|
||||
|
||||
//PIDs of last 2 received packets
|
||||
reg [3:0]pid0;
|
||||
reg [3:0]pid1;
|
||||
reg [1:0]toggle;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (rbyte_cnt==4'h1) & wre)
|
||||
begin
|
||||
pid1 <= pid0;
|
||||
pid0 <= data[3:0];
|
||||
end
|
||||
end
|
||||
|
||||
reg [3:0]setup_req;
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (rbyte_cnt==4'h3) & wre & (pid1==4'hd) )
|
||||
setup_req <= data[3:0];
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (rbyte_cnt==4'h6) & wre & (pid1==4'hd) )
|
||||
leds <= data[7:0];
|
||||
end
|
||||
|
||||
/*
|
||||
reg setup_val0;
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (rbyte_cnt==4'h4) & wre & (pid1==4'hd) )
|
||||
setup_val0 <= data[0];
|
||||
end
|
||||
*/
|
||||
|
||||
reg [3:0]setup_val;
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (rbyte_cnt==4'h5) & wre & (pid1==4'hd) )
|
||||
setup_val <= data[3:0];
|
||||
end
|
||||
|
||||
reg [3:0]setup_len;
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (rbyte_cnt==4'h8) & wre & (pid1==4'hd) )
|
||||
setup_len <= data[3:0];
|
||||
end
|
||||
|
||||
//sending bytes table
|
||||
reg [7:0]sptr;
|
||||
reg [7:0]sb; //byte for send and flag for last packet
|
||||
|
||||
always @*
|
||||
begin
|
||||
case(sptr)
|
||||
//ACK packet
|
||||
8'h00: sb = 8'h81; //SYN
|
||||
8'h01: sb = 8'hD2; //last in packet
|
||||
8'h02: sb = 8'h00;
|
||||
8'h03: sb = 8'h00;
|
||||
8'h04: sb = 8'h00;
|
||||
8'h05: sb = 8'h00;
|
||||
8'h06: sb = 8'h00;
|
||||
8'h07: sb = 8'h00;
|
||||
8'h08: sb = 8'h00;
|
||||
8'h09: sb = 8'h00;
|
||||
8'h0a: sb = 8'h00;
|
||||
8'h0b: sb = 8'h00;
|
||||
8'h0c: sb = 8'h00;
|
||||
8'h0d: sb = 8'h00;
|
||||
8'h0e: sb = 8'h00;
|
||||
8'h0f: sb = 8'h00;
|
||||
|
||||
//config descriptor
|
||||
8'h10: sb = 8'h8b; //SYN
|
||||
8'h11: sb = 8'h4B;
|
||||
8'h12: sb = 8'h12; //12 01 00 01 FF 00 00 08 23 f3
|
||||
8'h13: sb = 8'h01;
|
||||
8'h14: sb = 8'h00;
|
||||
8'h15: sb = 8'h01;
|
||||
8'h16: sb = 8'hff;
|
||||
8'h17: sb = 8'h00;
|
||||
8'h18: sb = 8'h00;
|
||||
8'h19: sb = 8'h08;
|
||||
8'h1a: sb = 8'h23;
|
||||
8'h1b: sb = 8'hf3; //last in packet
|
||||
8'h1c: sb = 8'h00;
|
||||
8'h1d: sb = 8'h00;
|
||||
8'h1e: sb = 8'h00;
|
||||
8'h1f: sb = 8'h00;
|
||||
|
||||
//config descriptor continued
|
||||
8'h20: sb = 8'h8b; //SYN
|
||||
8'h21: sb = 8'hC3;
|
||||
8'h22: sb = 8'hB9; //B9 04 00 03 00 02 02 01 14 4a
|
||||
8'h23: sb = 8'h04;
|
||||
8'h24: sb = 8'h00;
|
||||
8'h25: sb = 8'h03;
|
||||
8'h26: sb = 8'h00;
|
||||
8'h27: sb = 8'h02;
|
||||
8'h28: sb = 8'h02;
|
||||
8'h29: sb = 8'h00;
|
||||
8'h2a: sb = 8'hd5;
|
||||
8'h2b: sb = 8'h8a;
|
||||
8'h2c: sb = 8'h00;
|
||||
8'h2d: sb = 8'h00;
|
||||
8'h2e: sb = 8'h00;
|
||||
8'h2f: sb = 8'h00;
|
||||
|
||||
//config descriptor continued
|
||||
8'h30: sb = 8'h85; //SYN
|
||||
8'h31: sb = 8'h4B;
|
||||
8'h32: sb = 8'h00; //00 01 3f 8f
|
||||
8'h33: sb = 8'h01;
|
||||
8'h34: sb = 8'h3f;
|
||||
8'h35: sb = 8'h8f;
|
||||
8'h36: sb = 8'h00;
|
||||
8'h37: sb = 8'h00;
|
||||
8'h38: sb = 8'h00;
|
||||
8'h39: sb = 8'h00;
|
||||
8'h3a: sb = 8'h00;
|
||||
8'h3b: sb = 8'h00;
|
||||
8'h3c: sb = 8'h00;
|
||||
8'h3d: sb = 8'h00;
|
||||
8'h3e: sb = 8'h00;
|
||||
8'h3f: sb = 8'h00;
|
||||
|
||||
//empty IN
|
||||
8'h40: sb = 8'h83; //SYN
|
||||
8'h41: sb = 8'h4B;
|
||||
8'h42: sb = 8'h00;
|
||||
8'h43: sb = 8'h00;
|
||||
8'h44: sb = 8'h00;
|
||||
8'h45: sb = 8'h00;
|
||||
8'h46: sb = 8'h00;
|
||||
8'h47: sb = 8'h00;
|
||||
8'h48: sb = 8'h00;
|
||||
8'h49: sb = 8'h00;
|
||||
8'h4a: sb = 8'h00;
|
||||
8'h4b: sb = 8'h00;
|
||||
8'h4c: sb = 8'h00;
|
||||
8'h4d: sb = 8'h00;
|
||||
8'h4e: sb = 8'h00;
|
||||
8'h4f: sb = 8'h00;
|
||||
|
||||
//config descriptor configuration
|
||||
8'h50: sb = 8'h8b; //SYN
|
||||
8'h51: sb = 8'h4B;
|
||||
8'h52: sb = 8'h09;
|
||||
8'h53: sb = 8'h02;
|
||||
8'h54: sb = 8'h14;
|
||||
8'h55: sb = 8'h00;
|
||||
8'h56: sb = 8'h01;
|
||||
8'h57: sb = 8'h01;
|
||||
8'h58: sb = 8'h00;
|
||||
8'h59: sb = 8'h80;
|
||||
8'h5a: sb = 8'h0e;
|
||||
8'h5b: sb = 8'hd6;
|
||||
8'h5c: sb = 8'h00;
|
||||
8'h5d: sb = 8'h00;
|
||||
8'h5e: sb = 8'h00;
|
||||
8'h5f: sb = 8'h00;
|
||||
|
||||
//config descriptor configuration continued
|
||||
8'h60: sb = 8'h84; //SYN
|
||||
8'h61: sb = 8'hC3;
|
||||
8'h62: sb = 8'h0d;
|
||||
8'h63: sb = 8'h81;
|
||||
8'h64: sb = 8'h7a;
|
||||
8'h65: sb = 8'h00;
|
||||
8'h66: sb = 8'h00;
|
||||
8'h67: sb = 8'h00;
|
||||
8'h68: sb = 8'h00;
|
||||
8'h69: sb = 8'h00;
|
||||
8'h6a: sb = 8'h00;
|
||||
8'h6b: sb = 8'h00;
|
||||
8'h6c: sb = 8'h00;
|
||||
8'h6d: sb = 8'h00;
|
||||
8'h6e: sb = 8'h00;
|
||||
8'h6f: sb = 8'h00;
|
||||
|
||||
//config descriptor configuration
|
||||
8'h70: sb = 8'h8b; //SYN
|
||||
8'h71: sb = 8'h4B;
|
||||
8'h72: sb = 8'h09;
|
||||
8'h73: sb = 8'h02;
|
||||
8'h74: sb = 8'h14;
|
||||
8'h75: sb = 8'h00;
|
||||
8'h76: sb = 8'h01;
|
||||
8'h77: sb = 8'h01;
|
||||
8'h78: sb = 8'h00;
|
||||
8'h79: sb = 8'h80;
|
||||
8'h7a: sb = 8'h0e;
|
||||
8'h7b: sb = 8'hd6;
|
||||
8'h7c: sb = 8'h00;
|
||||
8'h7d: sb = 8'h00;
|
||||
8'h7e: sb = 8'h00;
|
||||
8'h7f: sb = 8'h00;
|
||||
|
||||
//config descriptor configuration continued
|
||||
8'h80: sb = 8'h8b; //SYN
|
||||
8'h81: sb = 8'hC3;
|
||||
8'h82: sb = 8'h0d;
|
||||
8'h83: sb = 8'h09;
|
||||
8'h84: sb = 8'h04;
|
||||
8'h85: sb = 8'h00;
|
||||
8'h86: sb = 8'h00;
|
||||
8'h87: sb = 8'h00;
|
||||
8'h88: sb = 8'hff;
|
||||
8'h89: sb = 8'h00;
|
||||
8'h8a: sb = 8'ha7;
|
||||
8'h8b: sb = 8'h19;
|
||||
8'h8c: sb = 8'h00;
|
||||
8'h8d: sb = 8'h00;
|
||||
8'h8e: sb = 8'h00;
|
||||
8'h8f: sb = 8'h00;
|
||||
|
||||
//config descriptor configuration continued
|
||||
8'h90: sb = 8'h87; //SYN
|
||||
8'h91: sb = 8'h4B;
|
||||
8'h92: sb = 8'h00;
|
||||
8'h93: sb = 8'h00;
|
||||
8'h94: sb = 8'h02;
|
||||
8'h95: sb = 8'h40;
|
||||
8'h96: sb = 8'hff;
|
||||
8'h97: sb = 8'h4b;
|
||||
8'h98: sb = 8'h00;
|
||||
8'h99: sb = 8'h00;
|
||||
8'h9a: sb = 8'h00;
|
||||
8'h9b: sb = 8'h00;
|
||||
8'h9c: sb = 8'h00;
|
||||
8'h9d: sb = 8'h00;
|
||||
8'h9e: sb = 8'h00;
|
||||
8'h9f: sb = 8'h00;
|
||||
|
||||
default:
|
||||
sb = 8'h00;
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [1:0]state;
|
||||
reg [3:0]pkt_len;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(sptr[3:0]==4'h0)
|
||||
pkt_len <= sb[3:0];
|
||||
/*
|
||||
if(sptr[3:0]==4'h0)
|
||||
sbyte <= {sb[7:4],4'b0000};
|
||||
else
|
||||
sbyte <= sb;
|
||||
|
||||
last_pkt_byte <= (sptr[3:0]==pkt_len);
|
||||
*/
|
||||
end
|
||||
|
||||
always @*
|
||||
begin
|
||||
if(sptr[3:0]==4'h0)
|
||||
sbyte = {sb[7:4],4'b0000};
|
||||
else
|
||||
sbyte = sb;
|
||||
|
||||
last_pkt_byte = (sptr[3:0]==pkt_len);
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if( (state==0) & (!EOP) )
|
||||
begin
|
||||
if(pid0==4'hd) //0x2D
|
||||
toggle <= 2'b00;
|
||||
else
|
||||
if(pid0==4'h9) //0x69
|
||||
toggle <= toggle + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or posedge EOP)
|
||||
begin
|
||||
if(EOP)
|
||||
begin
|
||||
//kind of reset
|
||||
start_pkt <= 1'b0;
|
||||
state <= 0;
|
||||
sptr <= 8'h00;
|
||||
end
|
||||
else
|
||||
begin
|
||||
start_pkt <= (state==2'b10);
|
||||
|
||||
case(state)
|
||||
0:
|
||||
begin
|
||||
//do nothing but just after EOP check last PIDs
|
||||
if( ((pid0==4'hb) | (pid0==4'h3)) & ((pid1==4'hd) | (pid1==4'h1)) ) // (0x4b or 0xc3) and (0x2d and 0xE1)
|
||||
begin
|
||||
state <= 2; //should send packet
|
||||
sptr[7:4] <= 4'h0; //packet will be ACK
|
||||
sptr[3:0] <= 4'h0;
|
||||
end
|
||||
else
|
||||
if( (pid0==4'h9)&(setup_req==4'h6)&(setup_val==4'h1))
|
||||
begin
|
||||
state <= 2; //should send packet
|
||||
sptr[7:4] <= 4'h1+toggle; //packet will be config descriptor
|
||||
sptr[3:0] <= 4'h0;
|
||||
end
|
||||
else
|
||||
if( (pid0==4'h9)&(setup_req==4'h6)&(setup_val==4'h2)&(setup_len==4'h9))
|
||||
begin
|
||||
state <= 2; //should send packet
|
||||
sptr[7:4] <= 4'h5+toggle; //packet will be config descriptor configuration
|
||||
sptr[3:0] <= 4'h0;
|
||||
end
|
||||
else
|
||||
if( (pid0==4'h9)&(setup_req==4'h6)&(setup_val==4'h2)&(setup_len!=4'h9))
|
||||
begin
|
||||
state <= 2; //should send packet
|
||||
sptr[7:4] <= 4'h7+toggle; //packet will be config descriptor configuration
|
||||
sptr[3:0] <= 4'h0;
|
||||
end
|
||||
else
|
||||
if(pid0==4'h9)
|
||||
begin
|
||||
state <= 2; //should send packet
|
||||
sptr[7:4] <= 4'h4; //empty IN
|
||||
sptr[3:0] <= 4'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
state <= 1; //should do nothing
|
||||
sptr<=8'h00;
|
||||
end
|
||||
end
|
||||
1:
|
||||
begin
|
||||
//do nothing
|
||||
state <= 1;
|
||||
sptr <= 8'h00;
|
||||
end
|
||||
2:
|
||||
begin
|
||||
//initiate send packet
|
||||
state <= 3;
|
||||
sptr <= sptr;
|
||||
end
|
||||
3:
|
||||
begin
|
||||
state <= 3;
|
||||
sptr[3:0] <= sptr[3:0] + show_next;
|
||||
sptr[7:4] <= sptr[7:4];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,172 +0,0 @@
|
||||
|
||||
//simplest low speed USB receive function
|
||||
|
||||
module 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_r,
|
||||
|
||||
//output received bytes interface
|
||||
output reg [7:0]rdata,
|
||||
output reg rdata_ready,
|
||||
output reg [3:0]rbyte_cnt,
|
||||
|
||||
output wire eop_rfe //receive EOP falling edge
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//receiver regs
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
reg [2:0]receiver_cnt;
|
||||
|
||||
//fix current USB line values
|
||||
reg [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 receiver
|
||||
assign eop_r = !(dp_input[0] | dp_input[1] | dm_input[0] | dm_input[1]);
|
||||
|
||||
//find edge of receive EOP
|
||||
assign eop_rfe = receiver_enabled & (eop_r);
|
||||
|
||||
//logic for enabling/disabling receiver
|
||||
reg receiver_enabled;
|
||||
always @(posedge clk or posedge reset )
|
||||
if(reset)
|
||||
receiver_enabled <= 1'b0;
|
||||
else
|
||||
if( eop_r) //disable on any EOP
|
||||
receiver_enabled <= 1'b0;
|
||||
else
|
||||
if( dp_input[0] ) //enable receiver on raising edge of DP line
|
||||
receiver_enabled <= enable;
|
||||
|
||||
//change on DP line defines strobing
|
||||
wire dp_change;
|
||||
assign dp_change = dp_input[0] ^ dp_input[1];
|
||||
|
||||
//generate clocked receiver strobe with this counter
|
||||
reg [2:0]clk_counter;
|
||||
always @(posedge clk or posedge reset )
|
||||
begin
|
||||
if(reset)
|
||||
clk_counter <= 3'b000;
|
||||
else
|
||||
begin
|
||||
//every edge on line resynchronizes receiver clock
|
||||
if(dp_change | eop_r)
|
||||
clk_counter <= 3'b000;
|
||||
else
|
||||
clk_counter <= clk_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
reg r_strobe;
|
||||
always @*
|
||||
r_strobe = (clk_counter == 3'b011) & receiver_enabled;
|
||||
|
||||
//on receiver strobe remember last fixed DP value
|
||||
reg last_fixed_dp;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
last_fixed_dp <= 1'b0;
|
||||
else
|
||||
begin
|
||||
if(r_strobe | eop_r)
|
||||
begin
|
||||
last_fixed_dp <= dp_input[1] & (~eop_r);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//count number of sequental ones for bit staffling
|
||||
reg [2:0]num_ones;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
num_ones <= 3'b000;
|
||||
else
|
||||
begin
|
||||
if(r_strobe)
|
||||
begin
|
||||
if(last_fixed_dp == dp_input[1])
|
||||
num_ones <= num_ones + 1'b1;
|
||||
else
|
||||
num_ones <= 3'b000;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//flag which mean that zero should be removed from bit stream because of bitstuffling
|
||||
wire do_remove_zero; assign do_remove_zero = (num_ones == 6);
|
||||
|
||||
//receiver process
|
||||
always @(posedge clk or posedge reset )
|
||||
begin
|
||||
if(reset)
|
||||
begin
|
||||
//kind of reset
|
||||
receiver_cnt <= 0;
|
||||
rdata <= 0;
|
||||
rdata_ready <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
if(r_strobe & (!do_remove_zero) | eop_r)
|
||||
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
|
||||
if(eop_r)
|
||||
begin
|
||||
receiver_cnt <= 0;
|
||||
rdata <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
receiver_cnt <= receiver_cnt + 1'b1;
|
||||
rdata <= { (last_fixed_dp == dp_input[1]) , rdata[7:1]};
|
||||
end
|
||||
end
|
||||
|
||||
//set write-enable signal (write into receiver buffer)
|
||||
rdata_ready <= (receiver_cnt == 7) & r_strobe & (!do_remove_zero) & (~eop_r);
|
||||
end
|
||||
end
|
||||
|
||||
//count number of received bytes
|
||||
always @(posedge clk or posedge reset )
|
||||
begin
|
||||
if(reset)
|
||||
rbyte_cnt <= 0;
|
||||
else
|
||||
begin
|
||||
if(eop_rfe)
|
||||
rbyte_cnt <= 0;
|
||||
else
|
||||
if(rdata_ready)
|
||||
rbyte_cnt <= rbyte_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,216 +0,0 @@
|
||||
|
||||
//low speed USB send function
|
||||
|
||||
module ls_usb_send(
|
||||
input wire reset,
|
||||
|
||||
//clock should be 12Mhz
|
||||
input wire clk,
|
||||
input wire bit_impulse,
|
||||
input wire eof,
|
||||
|
||||
input wire [7:0]sbyte, //byte for send
|
||||
input wire start_pkt, //start sending packet on that signal
|
||||
input wire last_pkt_byte, //mean send EOP at the end
|
||||
|
||||
//received from host
|
||||
input wire cmd_reset,
|
||||
input wire cmd_enable,
|
||||
|
||||
//usb BUS signals
|
||||
output reg dp,
|
||||
output reg dm,
|
||||
output reg bus_enable,
|
||||
|
||||
//usb BUS signals for
|
||||
output reg show_next, //request for next sending byte in packet
|
||||
output reg pkt_end //mean that packet was sent
|
||||
);
|
||||
|
||||
reg sbit;
|
||||
reg se0;
|
||||
always @*
|
||||
begin
|
||||
sbit = (prev_sbit ^ (!send_reg[0]) ^ (six_ones & send_reg[0])) & bus_ena_pkt;
|
||||
se0 = !(bus_ena_pkt ^ (bus_ena_pkt | bus_ena_prev[1]));
|
||||
show_next = (bit_count==3'h7) & sending_bit & bus_ena_pkt & (!last);
|
||||
pkt_end = bus_enable & (!bus_ena_pkt) & (bit_count==3'h3) & bit_impulse;
|
||||
end
|
||||
|
||||
//USB Reset and USB Enable become actual with frame start only
|
||||
reg usb_reset_fixed;
|
||||
reg usb_enable_fixed;
|
||||
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
begin
|
||||
usb_reset_fixed <= 1'b0;
|
||||
usb_enable_fixed <= 1'b0;
|
||||
end
|
||||
else
|
||||
if(eof)
|
||||
begin
|
||||
usb_reset_fixed <= cmd_reset;
|
||||
usb_enable_fixed <= cmd_enable;
|
||||
end
|
||||
end
|
||||
|
||||
//bus enable signal, which is related to packet sending
|
||||
reg bus_ena_pkt;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
bus_ena_pkt <= 1'b0;
|
||||
else
|
||||
begin
|
||||
if(start_pkt)
|
||||
bus_ena_pkt <= 1'b1;
|
||||
else
|
||||
if( sending_last_bit & last | eof)
|
||||
bus_ena_pkt <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
//delay shift register for bus enable for packet
|
||||
reg [2:0]bus_ena_prev;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
bus_ena_prev <= 3'b000;
|
||||
else
|
||||
if(bit_impulse)
|
||||
bus_ena_prev <= {bus_ena_prev[1:0],bus_ena_pkt};
|
||||
end
|
||||
|
||||
reg eof_f;
|
||||
always @(posedge clk or posedge reset)
|
||||
if(reset)
|
||||
eof_f <= 1'b0;
|
||||
else
|
||||
if(bit_impulse)
|
||||
eof_f <= eof;
|
||||
|
||||
//bus enable generation
|
||||
always @(posedge clk or posedge reset)
|
||||
if(reset)
|
||||
bus_enable <= 1'b0;
|
||||
else
|
||||
if(bit_impulse)
|
||||
bus_enable <= ((bus_ena_pkt | bus_ena_prev[2]))
|
||||
| usb_reset_fixed //bus enabled when reset
|
||||
| (usb_enable_fixed & (eof|eof_f) ); //bus enabled for keep-alive messages
|
||||
|
||||
wire suppress; assign suppress = usb_reset_fixed | (usb_enable_fixed & eof);
|
||||
|
||||
//make output on USB buses
|
||||
always @(posedge clk or posedge reset)
|
||||
if(reset)
|
||||
begin
|
||||
dp <= 1'b0;
|
||||
dm <= 1'b0;
|
||||
end
|
||||
else
|
||||
if(bit_impulse)
|
||||
begin
|
||||
dp <= suppress ? 1'b0 : ( sbit & se0 );
|
||||
dm <= suppress ? 1'b0 : ((!sbit) & se0 );
|
||||
end
|
||||
|
||||
//count number of sequental ONEs
|
||||
reg [2:0]ones_cnt;
|
||||
wire six_ones; assign six_ones = (ones_cnt==3'h6);
|
||||
wire sending_bit = bit_impulse & (!six_ones);
|
||||
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
ones_cnt <= 0;
|
||||
else
|
||||
begin
|
||||
if(eof)
|
||||
ones_cnt <= 0;
|
||||
else
|
||||
if(bit_impulse & bus_ena_pkt)
|
||||
begin
|
||||
if(sbit==prev_sbit)
|
||||
ones_cnt <= ones_cnt+1'b1;
|
||||
else
|
||||
ones_cnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//fix just sent bit
|
||||
reg prev_sbit;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
prev_sbit <= 1'b0;
|
||||
else
|
||||
begin
|
||||
if( start_pkt )
|
||||
prev_sbit <= 1'b0;
|
||||
else
|
||||
if(bit_impulse & bus_ena_pkt )
|
||||
prev_sbit <= sbit;
|
||||
end
|
||||
end
|
||||
|
||||
//fix flag about last byte in packet
|
||||
reg last;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
last <= 1'b0;
|
||||
else
|
||||
begin
|
||||
if( start_pkt )
|
||||
last <= 1'b0;
|
||||
else
|
||||
if(sending_last_bit)
|
||||
last <= last_pkt_byte;
|
||||
end
|
||||
end
|
||||
|
||||
//count number of sent bits
|
||||
reg [2:0]bit_count;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
bit_count <= 3'b000;
|
||||
else
|
||||
begin
|
||||
if( start_pkt )
|
||||
bit_count <= 3'b000;
|
||||
else
|
||||
if( sending_bit)
|
||||
bit_count <= bit_count + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire bit_count_eq7; assign bit_count_eq7 = (bit_count==3'h7);
|
||||
wire sending_last_bit = sending_bit & bit_count_eq7; //sending last bit in byte
|
||||
|
||||
//load/shift sending register
|
||||
reg [7:0]send_reg;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
send_reg <= 0;
|
||||
else
|
||||
begin
|
||||
if(eof)
|
||||
send_reg <= 0;
|
||||
else
|
||||
if(sending_bit | start_pkt)
|
||||
begin
|
||||
if(bit_count_eq7 | start_pkt)
|
||||
send_reg <= sbyte; //load first or next bytes for send
|
||||
else
|
||||
send_reg <= {1'b0, send_reg[7:1]}; //shift out byte
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,124 +0,0 @@
|
||||
|
||||
module serial(
|
||||
input wire reset,
|
||||
input wire clk100, //96MHz
|
||||
input wire rx,
|
||||
input wire [7:0]sbyte,
|
||||
input wire send,
|
||||
output reg [7:0]rx_byte,
|
||||
output reg rbyte_ready,
|
||||
output reg rbyte_ready2, //long variant of rbyte_ready
|
||||
output reg tx,
|
||||
output reg busy,
|
||||
output wire [7:0]rb
|
||||
);
|
||||
|
||||
parameter RCONST = 104; // 96000000Hz / 921600bps = 104
|
||||
|
||||
assign rb = {1'b0,rx_byte[7:1]};
|
||||
|
||||
reg [1:0]shr;
|
||||
always @(posedge clk100)
|
||||
shr <= {shr[0],rx};
|
||||
wire rxf; assign rxf = shr[1];
|
||||
|
||||
reg [15:0]cnt;
|
||||
reg [3:0]num_bits;
|
||||
|
||||
always @(posedge clk100 or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
cnt <= 0;
|
||||
else
|
||||
begin
|
||||
if(cnt == RCONST || num_bits==10)
|
||||
cnt <= 0;
|
||||
else
|
||||
cnt <= cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
reg [7:0]shift_reg;
|
||||
|
||||
always @(posedge clk100 or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
begin
|
||||
num_bits <= 0;
|
||||
shift_reg <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(num_bits==10 && rxf==1'b0)
|
||||
num_bits <= 0;
|
||||
else
|
||||
if(cnt == RCONST)
|
||||
num_bits <= num_bits + 1'b1;
|
||||
|
||||
if( cnt == RCONST/2 )
|
||||
shift_reg <= {rxf,shift_reg[7:1]};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk100 or posedge reset)
|
||||
if(reset)
|
||||
begin
|
||||
rx_byte <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(num_bits==9 && cnt == RCONST/2)
|
||||
rx_byte <= shift_reg[7:0];
|
||||
end
|
||||
|
||||
always @(posedge clk100 or posedge reset)
|
||||
if( reset )
|
||||
rbyte_ready <= 1'b0;
|
||||
else
|
||||
rbyte_ready <= (num_bits==9 && cnt == RCONST/2);
|
||||
|
||||
reg [8:0]send_reg;
|
||||
reg [3:0]send_num;
|
||||
reg [15:0]send_cnt;
|
||||
|
||||
wire send_time; assign send_time = send_cnt == RCONST;
|
||||
|
||||
always @(posedge clk100 or posedge reset)
|
||||
begin
|
||||
if(reset)
|
||||
begin
|
||||
send_reg <= 9'h1FF;
|
||||
send_num <= 10;
|
||||
send_cnt <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(send)
|
||||
send_cnt <= 0;
|
||||
else
|
||||
if(send_time)
|
||||
send_cnt <= 0;
|
||||
else
|
||||
send_cnt <= send_cnt + 1'b1;
|
||||
|
||||
if(send)
|
||||
begin
|
||||
send_reg <= {sbyte,1'b0};
|
||||
send_num <= 0;
|
||||
end
|
||||
else
|
||||
if(send_time && send_num!=10)
|
||||
begin
|
||||
send_reg <= {1'b1,send_reg[8:1]};
|
||||
send_num <= send_num + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @*
|
||||
begin
|
||||
busy = send_num!=10;
|
||||
tx = send_reg[0];
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,167 +0,0 @@
|
||||
|
||||
`timescale 1ns / 1ns
|
||||
|
||||
module tb;
|
||||
|
||||
//usb clock ~12MHz
|
||||
reg clock12 = 1'b0;
|
||||
always #42
|
||||
clock12 = ~clock12;
|
||||
|
||||
//system clock
|
||||
reg clock = 1'b0;
|
||||
always #5
|
||||
clock = ~clock;
|
||||
|
||||
reg reset=1'b0;
|
||||
wire idp;
|
||||
wire idm;
|
||||
reg [7:0]cmd=8'h00;
|
||||
reg cmd_wr=1'b0;
|
||||
wire odp, odm, ooe;
|
||||
wire [7:0]rdata;
|
||||
reg rdata_rd=1'b0;
|
||||
wire w_rd;
|
||||
|
||||
usbhost usbhost_(
|
||||
.rst( reset ),
|
||||
.iclk( clock ), //interface clk
|
||||
.wdata( cmd ), //interface commands and data
|
||||
.wr( cmd_wr ), //write
|
||||
.wr_level(),
|
||||
.rdata( rdata ),//result data
|
||||
.rd( w_rd ),//read
|
||||
.rdata_ready( w_rd ),
|
||||
|
||||
.cclk( clock12 ), //core clock, 12MHz
|
||||
|
||||
.i_dp( idp ),
|
||||
.i_dm( idm ),
|
||||
.o_dp( odp ),
|
||||
.o_dm( odm ),
|
||||
.o_oe( ooe )
|
||||
);
|
||||
|
||||
reg [31:0] cmd_time [0:255];
|
||||
reg [ 7:0] cmd_val [0:255];
|
||||
reg [7:0]idx;
|
||||
initial
|
||||
begin
|
||||
idx=0;
|
||||
cmd_time[idx]=100; cmd_val[idx]=8'h01; idx=idx+1; //get lines
|
||||
cmd_time[idx]=200; cmd_val[idx]=8'h32; idx=idx+1; //reset
|
||||
cmd_time[idx]=199130; cmd_val[idx]=8'h22; idx=idx+1; //enable
|
||||
cmd_time[idx]=203200; cmd_val[idx]=8'h03; idx=idx+1; //wait eof
|
||||
cmd_time[idx]=203201; cmd_val[idx]=8'h03; idx=idx+1; //wait eof
|
||||
cmd_time[idx]=203202; cmd_val[idx]=8'h44; idx=idx+1; //send pkt
|
||||
cmd_time[idx]=203203; cmd_val[idx]=8'h80; idx=idx+1;
|
||||
cmd_time[idx]=203204; cmd_val[idx]=8'h2d; idx=idx+1;
|
||||
cmd_time[idx]=203205; cmd_val[idx]=8'h00; idx=idx+1;
|
||||
cmd_time[idx]=203206; cmd_val[idx]=8'h10; idx=idx+1;
|
||||
cmd_time[idx]=203207; cmd_val[idx]=8'he4; idx=idx+1; //send pkt
|
||||
cmd_time[idx]=203208; cmd_val[idx]=8'h80; idx=idx+1;
|
||||
cmd_time[idx]=203209; cmd_val[idx]=8'hC4; idx=idx+1;
|
||||
cmd_time[idx]=203210; cmd_val[idx]=8'h80; idx=idx+1;
|
||||
cmd_time[idx]=203211; cmd_val[idx]=8'hc3; idx=idx+1;
|
||||
cmd_time[idx]=203212; cmd_val[idx]=8'h80; idx=idx+1;
|
||||
cmd_time[idx]=203213; cmd_val[idx]=8'h06; idx=idx+1;
|
||||
cmd_time[idx]=203214; cmd_val[idx]=8'h00; idx=idx+1;
|
||||
cmd_time[idx]=203215; cmd_val[idx]=8'h01; idx=idx+1;
|
||||
cmd_time[idx]=203216; cmd_val[idx]=8'h00; idx=idx+1;
|
||||
cmd_time[idx]=203217; cmd_val[idx]=8'h00; idx=idx+1;
|
||||
cmd_time[idx]=203218; cmd_val[idx]=8'h40; idx=idx+1;
|
||||
cmd_time[idx]=203219; cmd_val[idx]=8'h00; idx=idx+1;
|
||||
cmd_time[idx]=203220; cmd_val[idx]=8'hdd; idx=idx+1;
|
||||
cmd_time[idx]=203221; cmd_val[idx]=8'h94; idx=idx+1;
|
||||
cmd_time[idx]=203222; cmd_val[idx]=8'h05; idx=idx+1;
|
||||
cmd_time[idx]=203225; cmd_val[idx]=8'h06; idx=idx+1;
|
||||
idx=0;
|
||||
end
|
||||
|
||||
reg [32:0]counter=0;
|
||||
always @(posedge clock)
|
||||
begin
|
||||
counter<=counter+1;
|
||||
if( counter==cmd_time[idx] )
|
||||
begin
|
||||
cmd <= cmd_val[idx];
|
||||
cmd_wr<=1'b1;
|
||||
idx<=idx+1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cmd <= 0;
|
||||
cmd_wr<=1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @( posedge usbhost_.bit_impulse )
|
||||
if( usbhost_.bit_time==300)
|
||||
$dumpoff;
|
||||
else
|
||||
if( usbhost_.bit_time==1450)
|
||||
$dumpon;
|
||||
|
||||
wire [7:0]w_send_byte;
|
||||
wire w_start_pkt;
|
||||
wire w_last;
|
||||
wire w_show_next;
|
||||
wire w_pkt_end;
|
||||
|
||||
ls_usb_send ls_usb_send_(
|
||||
.reset( reset ),
|
||||
.clk( clock12 ),
|
||||
.bit_impulse( usbhost_.bit_impulse ),
|
||||
.eof( usbhost_.eof ),
|
||||
.sbyte( w_send_byte ), //byte for send
|
||||
.start_pkt( w_start_pkt ), //start sending packet on that signal
|
||||
.last_pkt_byte( w_last ), //mean send EOP at the end
|
||||
.cmd_reset( 1'b0 ),
|
||||
.cmd_enable( 1'b1 ),
|
||||
.dp( idp ),
|
||||
.dm( idm ),
|
||||
.bus_enable( ),
|
||||
.show_next( w_show_next ), //request for next sending byte in packet
|
||||
.pkt_end( w_pkt_end ) //mean that packet was sent
|
||||
);
|
||||
|
||||
reg [7:0]send_state = 0;
|
||||
always @(posedge clock12)
|
||||
if( send_state==0 && usbhost_.enable_recv )
|
||||
send_state<=1;
|
||||
else
|
||||
if( send_state==1)
|
||||
send_state<=2;
|
||||
else
|
||||
if( send_state==2 && w_show_next )
|
||||
send_state<=3;
|
||||
else
|
||||
if( send_state==3 && w_show_next )
|
||||
send_state<=4;
|
||||
else
|
||||
if( send_state==4 && w_show_next )
|
||||
send_state<=5;
|
||||
|
||||
assign w_start_pkt = (send_state==1);
|
||||
assign w_send_byte = (send_state==1) ? 8'h80 :
|
||||
(send_state==2) ? 8'hA5 :
|
||||
(send_state==3) ? 8'h73 :
|
||||
(send_state==4) ? 8'h23 :
|
||||
(send_state==5) ? 8'h11 : 0;
|
||||
assign w_last = (send_state==4);
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("out.vcd");
|
||||
$dumpvars(0,tb);
|
||||
|
||||
reset = 1'b1;
|
||||
#500;
|
||||
reset = 1'b0;
|
||||
|
||||
|
||||
#6000000;
|
||||
$finish();
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,391 +0,0 @@
|
||||
|
||||
module usbhost(
|
||||
//interface
|
||||
input wire rst,
|
||||
input wire iclk, //interface clk
|
||||
input wire [7:0]wdata, //interface commands and data
|
||||
input wire wr, //write
|
||||
output wire [1:0]wr_level,
|
||||
output wire [7:0]rdata, //result data
|
||||
input wire rd, //read
|
||||
output wire rdata_ready,
|
||||
|
||||
//core
|
||||
input wire cclk, //core clock, 12MHz
|
||||
|
||||
input wire i_dp,
|
||||
input wire i_dm,
|
||||
output wire o_dp,
|
||||
output wire o_dm,
|
||||
output wire o_oe,
|
||||
output wire [7:0]leds
|
||||
);
|
||||
|
||||
//controller serial bytes protocol
|
||||
localparam CMD_GET_LINES = 4'h1; //controller must once poll and return one byte state of USB lines
|
||||
localparam CMD_BUS_CTRL = 4'h2; //controller must set bus to reset/normal and/or or enabled/disabled state
|
||||
//reset state - dm/dm in zero
|
||||
//enabled state when no reset and 1ms periodic SE0 impulses go
|
||||
localparam CMD_WAIT_EOF = 4'h3; //controller just waits EOF/SE0 condition
|
||||
//any bus operation should start from this, so any read/write start //at begin of frame
|
||||
localparam CMD_SEND_PKT = 4'h4; //new packed will be sent to bus. high 4 bits of cmd byte mean data length
|
||||
localparam CMD_READ_PKT = 4'h5;
|
||||
localparam CMD_AUTO_ACK = 4'h6;
|
||||
|
||||
//controller state machine states
|
||||
localparam STATE_IDLE = 0;
|
||||
localparam STATE_READ_CMD = 1;
|
||||
localparam STATE_GOT_CMD = 2;
|
||||
localparam STATE_READ_LINES = 3;
|
||||
localparam STATE_BUS_CONTROL = 4;
|
||||
localparam STATE_WAIT_EOF = 5;
|
||||
localparam STATE_WAIT_NO_EOF = 6;
|
||||
localparam STATE_WAIT_BIT0 = 7;
|
||||
localparam STATE_WAIT_BIT1 = 8;
|
||||
localparam STATE_FETCH_SEND_BYTE = 9;
|
||||
localparam STATE_CATCH_SEND_BYTE = 10;
|
||||
localparam STATE_FETCH_SEND_BYTE1 = 11;
|
||||
localparam STATE_CATCH_SEND_BYTE1 = 12;
|
||||
localparam STATE_SENDING = 13;
|
||||
localparam STATE_WAIT_ACK = 14;
|
||||
localparam STATE_READ_DATA = 15;
|
||||
localparam STATE_READ_DATA_ALL = 16;
|
||||
localparam STATE_COPY_TMP_PKT = 17;
|
||||
localparam STATE_COPY_TMP_PKT2 = 18;
|
||||
localparam STATE_SEND_ACK_WAIT_BIT0 = 19;
|
||||
localparam STATE_SEND_ACK_WAIT_BIT1 = 20;
|
||||
localparam STATE_SEND_ACK_80 = 21;
|
||||
localparam STATE_SEND_ACK_D2 = 22;
|
||||
|
||||
reg [7:0]state = 0;
|
||||
|
||||
//make low speed bit impulse
|
||||
reg [2:0]cnt;
|
||||
reg bit_impulse;
|
||||
always @( posedge cclk or posedge rst )
|
||||
begin
|
||||
if(rst)
|
||||
begin
|
||||
cnt <= 0;
|
||||
bit_impulse <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cnt <= cnt + 1;
|
||||
bit_impulse <= (cnt==7);
|
||||
end
|
||||
end
|
||||
|
||||
//make frame EOF impulse
|
||||
reg eof;
|
||||
reg [10:0]bit_time;
|
||||
always @(posedge cclk or posedge rst)
|
||||
begin
|
||||
if(rst)
|
||||
begin
|
||||
bit_time <= 0;
|
||||
eof <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(bit_impulse)
|
||||
begin
|
||||
if(bit_time==1499)
|
||||
bit_time <= 0;
|
||||
else
|
||||
bit_time <= bit_time + 1'b1;
|
||||
end
|
||||
|
||||
eof <= (bit_time > 1497 );
|
||||
end
|
||||
end
|
||||
|
||||
wire in_empty;
|
||||
wire [1:0]in_rd_level;
|
||||
wire [7:0]in_cmd;
|
||||
reg in_rd=1'b0;
|
||||
|
||||
//input data and commands go into FIFO
|
||||
generic_fifo_dc_gray #( .dw(8), .aw(6) ) fifo_in(
|
||||
.rst( ~rst ),
|
||||
.rd_clk( cclk ),
|
||||
.wr_clk( iclk ),
|
||||
.clr( 1'b0 ),
|
||||
.din( wdata ),
|
||||
.we( wr ),
|
||||
.dout( in_cmd ),
|
||||
.rd( in_rd ),
|
||||
.full(),
|
||||
.empty( in_empty ),
|
||||
.wr_level( wr_level ),
|
||||
.rd_level( in_rd_level )
|
||||
);
|
||||
|
||||
assign leds = in_cmd;
|
||||
|
||||
//result data go to output FIFO
|
||||
wire [7:0]out_data;
|
||||
wire out_data_wr;
|
||||
wire empty;
|
||||
assign rdata_ready = ~empty;
|
||||
|
||||
generic_fifo_dc_gray #( .dw(8), .aw(4) ) fifo_out(
|
||||
.rst( ~rst ),
|
||||
.rd_clk( iclk ),
|
||||
.wr_clk( cclk ),
|
||||
.clr( 1'b0 ),
|
||||
.din( out_data ),
|
||||
.we( out_data_wr ),
|
||||
.dout( rdata ),
|
||||
.rd( rd ),
|
||||
.full(),
|
||||
.empty( empty ),
|
||||
.wr_level( ),
|
||||
.rd_level( )
|
||||
);
|
||||
|
||||
wire [7:0]usb_rdata;
|
||||
wire usb_rdata_ready;
|
||||
wire eop_r;
|
||||
wire enable_recv;
|
||||
|
||||
//Need temporary fifo to store USB packet received from USB bus.
|
||||
//When USB packet received, then we know actual packet length and then
|
||||
//we can copy temporary data into output fifo, but first in protocol go packet length encoded with command
|
||||
wire [7:0]tmp_fifo_data;
|
||||
wire tmp_fifo_rd; assign tmp_fifo_rd = (~tmp_fifo_empty) & (state==STATE_COPY_TMP_PKT);
|
||||
wire tmp_fifo_empty;
|
||||
generic_fifo_dc_gray #( .dw(8), .aw(4) ) fifo_out_tmp(
|
||||
.rst( ~rst ),
|
||||
.rd_clk( cclk ),
|
||||
.wr_clk( cclk ),
|
||||
.clr( state==STATE_READ_DATA ), //reset tmp fifo at begin of any recv packet
|
||||
.din( usb_rdata ),
|
||||
.we( usb_rdata_ready ),
|
||||
.dout( tmp_fifo_data ),
|
||||
.rd( tmp_fifo_rd ),
|
||||
.full(),
|
||||
.empty( tmp_fifo_empty ),
|
||||
.wr_level( ),
|
||||
.rd_level( )
|
||||
);
|
||||
|
||||
assign out_data =
|
||||
(state==STATE_READ_LINES) ? { 2'b00, i_dp, i_dm, CMD_GET_LINES }:
|
||||
( (state==STATE_READ_DATA_ALL) & got_recv_pkt_length) ? { usb_rbyte_cnt, CMD_READ_PKT }:
|
||||
tmp_fifo_data;
|
||||
|
||||
assign out_data_wr =
|
||||
(state==STATE_READ_LINES) |
|
||||
((state==STATE_READ_DATA_ALL) & got_recv_pkt_length) |
|
||||
(state==STATE_COPY_TMP_PKT & (~tmp_fifo_empty) );
|
||||
|
||||
assign enable_recv = (state==STATE_READ_DATA) | (state==STATE_READ_DATA_ALL);
|
||||
|
||||
always @*
|
||||
in_rd = (state==STATE_READ_CMD) || (state==STATE_FETCH_SEND_BYTE) || (state==STATE_FETCH_SEND_BYTE1);
|
||||
|
||||
reg cmd_ready=1'b0;
|
||||
always @( posedge cclk )
|
||||
cmd_ready <= in_rd;
|
||||
|
||||
reg [7:0]in_cmd_;
|
||||
always @( posedge cclk )
|
||||
if( cmd_ready && state==STATE_GOT_CMD )
|
||||
in_cmd_ <= in_cmd;
|
||||
|
||||
reg [7:0]send_byte;
|
||||
always @( posedge cclk )
|
||||
if( cmd_ready && (state==STATE_CATCH_SEND_BYTE || state==STATE_CATCH_SEND_BYTE1) )
|
||||
send_byte <= in_cmd;
|
||||
|
||||
reg bus_reset;
|
||||
reg bus_enable;
|
||||
always @( posedge cclk or posedge rst )
|
||||
begin
|
||||
if(rst)
|
||||
begin
|
||||
bus_reset <= 1'b0;
|
||||
bus_enable <= 1'b0;
|
||||
end
|
||||
else
|
||||
if( state==STATE_BUS_CONTROL )
|
||||
begin
|
||||
bus_reset <= in_cmd_[4];
|
||||
bus_enable <= in_cmd_[5];
|
||||
end
|
||||
end
|
||||
|
||||
always @( posedge cclk )
|
||||
begin
|
||||
case( state )
|
||||
STATE_IDLE: begin
|
||||
if( ~in_empty )
|
||||
state <= STATE_READ_CMD;
|
||||
end
|
||||
STATE_READ_CMD: begin
|
||||
state <= STATE_GOT_CMD;
|
||||
end
|
||||
STATE_GOT_CMD: begin
|
||||
case( in_cmd[3:0] )
|
||||
CMD_GET_LINES: state <= STATE_READ_LINES;
|
||||
CMD_BUS_CTRL: state <= STATE_BUS_CONTROL;
|
||||
CMD_WAIT_EOF: state <= STATE_WAIT_EOF;
|
||||
CMD_SEND_PKT: state <= STATE_WAIT_BIT0;
|
||||
CMD_READ_PKT: state <= STATE_READ_DATA;
|
||||
CMD_AUTO_ACK: state <= STATE_SEND_ACK_WAIT_BIT0;
|
||||
default:
|
||||
state <= STATE_IDLE;
|
||||
endcase
|
||||
end
|
||||
STATE_READ_LINES: begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
STATE_BUS_CONTROL: begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
STATE_WAIT_EOF: begin
|
||||
if( bit_impulse & eof )
|
||||
state <= STATE_WAIT_NO_EOF;
|
||||
end
|
||||
STATE_WAIT_NO_EOF: begin
|
||||
if( bit_impulse & (~eof) )
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
STATE_WAIT_BIT0: begin
|
||||
if( bit_impulse &(~eof) )
|
||||
state <= STATE_WAIT_BIT1;
|
||||
end
|
||||
STATE_WAIT_BIT1: begin
|
||||
if( bit_impulse )
|
||||
state <= STATE_FETCH_SEND_BYTE;
|
||||
end
|
||||
STATE_FETCH_SEND_BYTE: begin
|
||||
state <= STATE_CATCH_SEND_BYTE;
|
||||
end
|
||||
STATE_CATCH_SEND_BYTE: begin
|
||||
if( start_pkt)
|
||||
state <= STATE_FETCH_SEND_BYTE1;
|
||||
end
|
||||
STATE_FETCH_SEND_BYTE1: begin
|
||||
state <= STATE_CATCH_SEND_BYTE1;
|
||||
end
|
||||
STATE_CATCH_SEND_BYTE1: begin
|
||||
state <= STATE_SENDING;
|
||||
end
|
||||
STATE_SENDING: begin
|
||||
if( show_next & num_bytes_sent<in_cmd_[7:4])
|
||||
state <= STATE_FETCH_SEND_BYTE1;
|
||||
else
|
||||
if( pkt_end )
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
STATE_SEND_ACK_WAIT_BIT0: begin
|
||||
//here we may decide to ACK or not to ACK and got to STATE_IDLE..
|
||||
//if recent received byte is 0x5A(NAK) then no need to auto-ACK
|
||||
if( last_recv_byte==8'h5A )
|
||||
state <= STATE_IDLE;
|
||||
else
|
||||
if( bit_impulse )
|
||||
state <= STATE_SEND_ACK_WAIT_BIT1;
|
||||
end
|
||||
|
||||
STATE_SEND_ACK_WAIT_BIT1: begin
|
||||
if( bit_impulse )
|
||||
state <= STATE_SEND_ACK_80;
|
||||
end
|
||||
STATE_SEND_ACK_80: begin
|
||||
state <= STATE_SEND_ACK_D2;
|
||||
end
|
||||
STATE_SEND_ACK_D2: begin
|
||||
if(show_next)
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
STATE_WAIT_ACK: begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
STATE_READ_DATA: begin
|
||||
state <= STATE_READ_DATA_ALL;
|
||||
end
|
||||
STATE_READ_DATA_ALL: begin
|
||||
if( eof | eop_r )
|
||||
state <= STATE_COPY_TMP_PKT;
|
||||
end
|
||||
STATE_COPY_TMP_PKT: begin
|
||||
state <= STATE_COPY_TMP_PKT2;
|
||||
end
|
||||
STATE_COPY_TMP_PKT2: begin
|
||||
if( tmp_fifo_empty )
|
||||
state <= STATE_IDLE;
|
||||
else
|
||||
state <= STATE_COPY_TMP_PKT;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [3:0]num_bytes_sent;
|
||||
always @( posedge cclk )
|
||||
if( state==STATE_GOT_CMD )
|
||||
num_bytes_sent<= 1;
|
||||
else
|
||||
if( start_pkt | show_next )
|
||||
num_bytes_sent <= num_bytes_sent+1;
|
||||
|
||||
wire start_pkt; assign start_pkt = (state==STATE_CATCH_SEND_BYTE) & bit_impulse;
|
||||
wire pkt_end;
|
||||
|
||||
wire [7:0]actual_send_byte;
|
||||
assign actual_send_byte =
|
||||
(state==STATE_SEND_ACK_80) ? 8'h80 : //maybe auto-ack or real data from SW
|
||||
(state==STATE_SEND_ACK_D2) ? 8'hD2 : send_byte;
|
||||
|
||||
wire actual_start_pkt;
|
||||
assign actual_start_pkt = start_pkt | (state==STATE_SEND_ACK_80);
|
||||
|
||||
wire actual_last_pkt_byte;
|
||||
assign actual_last_pkt_byte = (num_bytes_sent==in_cmd_[7:4]) | (state==STATE_SEND_ACK_D2);
|
||||
|
||||
wire show_next;
|
||||
ls_usb_send ls_usb_send_(
|
||||
.reset( rst ),
|
||||
.clk( cclk ),
|
||||
.bit_impulse( bit_impulse ),
|
||||
.eof( eof ),
|
||||
.sbyte( actual_send_byte ), //byte for send
|
||||
.start_pkt( actual_start_pkt ), //start sending packet on that signal
|
||||
.last_pkt_byte( actual_last_pkt_byte ), //mean send EOP at the end
|
||||
.cmd_reset( bus_reset ),
|
||||
.cmd_enable( bus_enable ),
|
||||
.dp( o_dp ),
|
||||
.dm( o_dm ),
|
||||
.bus_enable( o_oe ),
|
||||
.show_next( show_next ), //request for next sending byte in packet
|
||||
.pkt_end( pkt_end ) //mean that packet was sent
|
||||
);
|
||||
|
||||
wire [3:0]usb_rbyte_cnt;
|
||||
ls_usb_recv ls_usb_recv_(
|
||||
.reset( rst ),
|
||||
.clk( cclk ),
|
||||
.dp( i_dp ),
|
||||
.dm( i_dm ),
|
||||
.enable( enable_recv ),
|
||||
.eop_r( eop_r ),
|
||||
.rdata( usb_rdata ),
|
||||
.rdata_ready( usb_rdata_ready ),
|
||||
.rbyte_cnt( usb_rbyte_cnt ),
|
||||
.eop_rfe( )
|
||||
);
|
||||
|
||||
reg [7:0]last_recv_byte;
|
||||
always @(posedge cclk)
|
||||
if(usb_rdata_ready)
|
||||
last_recv_byte <= usb_rdata;
|
||||
|
||||
reg eop_r_;
|
||||
always @(posedge cclk)
|
||||
eop_r_ <= eop_r;
|
||||
wire got_recv_pkt_length;
|
||||
assign got_recv_pkt_length = ((eop_r_==1'b0) && (eop_r==1'b1));
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user