1
0
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:
UzixLS
2021-06-13 13:43:13 +03:00
parent 463e92f8c7
commit eb6f3c1463
6 changed files with 0 additions and 1453 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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