mirror of
https://github.com/avakar/usbcorev.git
synced 2024-10-22 02:17:39 +08:00
fb2e32dc58
The module works correctly during USB enumeration, no more tests were performed at this point. No documentation or tests.
164 lines
3.0 KiB
Verilog
164 lines
3.0 KiB
Verilog
module usb_crc5(
|
|
input rst_n,
|
|
input clk,
|
|
input clken,
|
|
input d,
|
|
output valid
|
|
);
|
|
|
|
reg[4:0] r;
|
|
reg[4:0] next;
|
|
|
|
wire top = r[4];
|
|
assign valid = (next == 5'b01100);
|
|
|
|
always @(*) begin
|
|
if (top == d)
|
|
next = { r[3], r[2], r[1], r[0], 1'b0 };
|
|
else
|
|
next = { r[3], r[2], !r[1], r[0], 1'b1 };
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
r <= 5'b11111;
|
|
end else if (clken) begin
|
|
r <= next;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
//---------------------------------------------------------------------
|
|
module usb_crc16(
|
|
input rst_n,
|
|
input clk,
|
|
input clken,
|
|
input d,
|
|
|
|
input dump,
|
|
output out,
|
|
output valid
|
|
);
|
|
|
|
reg[15:0] r;
|
|
reg[15:0] next;
|
|
|
|
assign out = r[15];
|
|
assign valid = (next == 16'b1000000000001101);
|
|
|
|
always @(*) begin
|
|
if (dump || out == d)
|
|
next = { r[14:0], 1'b0 };
|
|
else
|
|
next = { !r[14], r[13:2], !r[1], r[0], 1'b1 };
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
r <= 16'hffff;
|
|
end else if (clken) begin
|
|
r <= next;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
//---------------------------------------------------------------------
|
|
module usb_clk_recovery(
|
|
input rst_n,
|
|
input clk,
|
|
input i,
|
|
output strobe
|
|
);
|
|
|
|
reg[1:0] cntr;
|
|
reg prev_i;
|
|
|
|
assign strobe = cntr == 1'b0;
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
cntr <= 1'b0;
|
|
prev_i <= 1'b0;
|
|
end else begin
|
|
if (i == prev_i) begin
|
|
cntr <= cntr - 1'b1;
|
|
end else begin
|
|
cntr <= 1'b1;
|
|
end
|
|
prev_i <= i;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
//---------------------------------------------------------------------
|
|
module usb_bit_destuff(
|
|
input rst_n,
|
|
input clk,
|
|
input clken,
|
|
input d,
|
|
output strobe);
|
|
|
|
reg[6:0] data;
|
|
assign strobe = clken && (data != 7'b0111111);
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
data <= 7'b0000000;
|
|
end else if (clken) begin
|
|
data <= { data[5:0], d };
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
//---------------------------------------------------------------------
|
|
module usb_sync_detect(
|
|
input rst_n,
|
|
input clk,
|
|
input clken,
|
|
input j,
|
|
input se0,
|
|
output sync);
|
|
|
|
// 3KJ's followed by 2K's
|
|
reg[6:0] data;
|
|
assign sync = (data == 7'b0101010 && !j && !se0);
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
data <= 1'd0;
|
|
end else if (clken) begin
|
|
data <= { data[5:0], j || se0 };
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
//---------------------------------------------------------------------
|
|
module usb_reset_detect(
|
|
input rst_n,
|
|
input clk,
|
|
input se0,
|
|
output usb_rst);
|
|
|
|
reg[18:0] cntr;
|
|
assign usb_rst = cntr == 1'b0;
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
cntr <= 1'b0;
|
|
end else begin
|
|
if (se0) begin
|
|
if (!usb_rst)
|
|
cntr <= cntr - 1'b1;
|
|
end else begin
|
|
cntr <= 19'd480000;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|