usb fixed?

This commit is contained in:
Polprzewodnikowy 2022-02-04 19:23:32 +01:00
parent 8493c2edb1
commit 8da9359ee1
4 changed files with 207 additions and 139 deletions

View File

@ -19,7 +19,7 @@
# #
# Quartus Prime # Quartus Prime
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition # Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
# Date created = 19:00:58 February 02, 2022 # Date created = 19:19:14 February 04, 2022
# #
# -------------------------------------------------------------------------- # # -------------------------------------------------------------------------- #
# #
@ -88,11 +88,9 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/vendor/vendor_reconfigure.sv
# Pin & Location Assignments # Pin & Location Assignments
# ========================== # ==========================
set_location_assignment PIN_6 -to o_usb_clk set_location_assignment PIN_6 -to o_usb_cs
set_location_assignment PIN_7 -to io_usb_miosi[2] set_location_assignment PIN_7 -to i_usb_miso
set_location_assignment PIN_8 -to io_usb_miosi[3] set_location_assignment PIN_8 -to o_usb_clk
set_location_assignment PIN_10 -to io_usb_miosi[0]
set_location_assignment PIN_11 -to io_usb_miosi[1]
set_location_assignment PIN_12 -to i_uart_rxd set_location_assignment PIN_12 -to i_uart_rxd
set_location_assignment PIN_13 -to o_uart_txd set_location_assignment PIN_13 -to o_uart_txd
set_location_assignment PIN_17 -to o_led set_location_assignment PIN_17 -to o_led
@ -165,13 +163,15 @@ set_location_assignment PIN_114 -to o_sd_clk
set_location_assignment PIN_118 -to io_sd_cmd set_location_assignment PIN_118 -to io_sd_cmd
set_location_assignment PIN_119 -to io_sd_dat[3] set_location_assignment PIN_119 -to io_sd_dat[3]
set_location_assignment PIN_120 -to io_sd_dat[2] set_location_assignment PIN_120 -to io_sd_dat[2]
set_location_assignment PIN_121 -to io_usb_miosi[5]
set_location_assignment PIN_122 -to io_usb_miosi[7]
set_location_assignment PIN_123 -to o_n64_irq set_location_assignment PIN_123 -to o_n64_irq
set_location_assignment PIN_124 -to io_usb_miosi[6] set_location_assignment PIN_124 -to io_usb_miosi[7]
set_location_assignment PIN_126 -to io_usb_miosi[4] set_location_assignment PIN_127 -to io_usb_miosi[6]
set_location_assignment PIN_140 -to o_usb_cs set_location_assignment PIN_130 -to io_usb_miosi[4]
set_location_assignment PIN_141 -to i_usb_miso set_location_assignment PIN_131 -to io_usb_miosi[5]
set_location_assignment PIN_134 -to io_usb_miosi[3]
set_location_assignment PIN_135 -to io_usb_miosi[2]
set_location_assignment PIN_140 -to io_usb_miosi[1]
set_location_assignment PIN_141 -to io_usb_miosi[0]
# Classic Timing Assignments # Classic Timing Assignments
# ========================== # ==========================
@ -231,34 +231,39 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# Pin & Location Assignments # Pin & Location Assignments
# ========================== # ==========================
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_aleh set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_aleh
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_read set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_read
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_write set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_write
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*] set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cs set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ras set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cas set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_we set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_a[*] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_a[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ba[*] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ba[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cas
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cs
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ras
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_we
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*] set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sdram_dq[*] set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[*]
# Fitter Assignments # Fitter Assignments
# ================== # ==================
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[*]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_rxd set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_rxd
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq

View File

@ -49,11 +49,11 @@ set_multicycle_path -hold -end 1 -from [get_clocks {sdram_clk}] -to [get_clocks
# FT1248 timings # FT1248 timings
set_output_delay -clock [get_clocks {usb_clk}] -max 5.0 [get_ports {io_usb_miosi[*] o_usb_cs}] set_output_delay -clock [get_clocks {usb_clk}] -max 2.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_output_delay -clock [get_clocks {usb_clk}] -min -5.0 [get_ports {io_usb_miosi[*] o_usb_cs}] set_output_delay -clock [get_clocks {usb_clk}] -min -1.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_input_delay -clock [get_clocks {usb_clk}] -max 5.0 [get_ports {io_usb_miosi[*] i_usb_miso}] set_input_delay -clock [get_clocks {usb_clk}] -max 5.0 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_input_delay -clock [get_clocks {usb_clk}] -min 5.0 [get_ports {io_usb_miosi[*] i_usb_miso}] set_input_delay -clock [get_clocks {usb_clk}] -min 2.5 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_multicycle_path -setup -start 2 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}] set_multicycle_path -setup -start 2 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}]
set_multicycle_path -hold -start 3 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}] set_multicycle_path -hold -start 3 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}]

View File

@ -27,6 +27,7 @@ module usb_ft1248 (
logic rx_full; logic rx_full;
logic rx_almost_full; logic rx_almost_full;
logic rx_write; logic rx_write;
logic [7:0] rx_wdata;
logic tx_empty; logic tx_empty;
logic tx_almost_empty; logic tx_almost_empty;
@ -45,7 +46,7 @@ module usb_ft1248 (
.full(rx_full), .full(rx_full),
.almost_full(rx_almost_full), .almost_full(rx_almost_full),
.wrreq(rx_write), .wrreq(rx_write),
.data(usb_miosi) .data(rx_wdata)
); );
intel_fifo_8 fifo_8_tx_inst ( intel_fifo_8 fifo_8_tx_inst (
@ -63,6 +64,29 @@ module usb_ft1248 (
.data(tx_wdata) .data(tx_wdata)
); );
logic [7:0] usb_miosi_out;
logic usb_oe;
logic ft_clk;
logic ft_cs;
logic ft_miso;
logic [7:0] ft_miosi_in;
logic [7:0] ft_miosi_out;
logic ft_oe;
always_ff @(posedge clk) begin
usb_clk <= ft_clk;
usb_cs <= ft_cs;
ft_miso <= usb_miso;
ft_miosi_in <= usb_miosi;
usb_miosi_out <= ft_miosi_out;
usb_oe <= ft_oe;
end
always_comb begin
usb_miosi = usb_oe ? usb_miosi_out : 8'hZZ;
end
typedef enum bit [2:0] { typedef enum bit [2:0] {
STATE_IDLE, STATE_IDLE,
STATE_SELECT, STATE_SELECT,
@ -80,163 +104,202 @@ module usb_ft1248 (
CMD_WRITE_BUFFER_FLUSH = 8'h08 CMD_WRITE_BUFFER_FLUSH = 8'h08
} e_command; } e_command;
logic usb_miosi_oe;
logic write_buffer_flush_pending;
logic write_modem_status_pending;
logic [4:0] modem_status_counter;
logic modem_status_read;
logic last_reset_status;
logic reset_reply;
logic [3:0] phase;
logic [7:0] usb_cmd;
e_state state; e_state state;
e_state next_state;
always_comb begin e_command cmd;
usb_miosi = 8'hZZ; e_command next_cmd;
if (usb_miosi_oe) begin logic [3:0] phase;
usb_miosi = 8'h00; logic reset_reply;
if ((state == STATE_COMMAND) || (state == STATE_STATUS)) begin logic last_reset_status;
usb_miosi = usb_cmd; logic [4:0] modem_status_counter;
end logic write_modem_status_pending;
if ((state == STATE_DATA) || (state == STATE_DESELECT)) begin logic write_buffer_flush_pending;
if (usb_cmd == CMD_WRITE) begin
usb_miosi = tx_rdata;
end
if (usb_cmd == CMD_WRITE_MODEM_STATUS) begin
usb_miosi = {2'b00, reset_reply, 5'b00000};
end
end
end
end
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
rx_write <= 1'b0; state <= next_state;
tx_read <= 1'b0; cmd <= next_cmd;
modem_status_read <= 1'b0;
phase <= {phase[2:0], phase[3]};
if (reset) begin phase <= {phase[2:0], phase[3]};
usb_clk <= 1'b0; if (state == STATE_IDLE) begin
usb_cs <= 1'b1; phase <= 4'b0100;
usb_miosi_oe <= 1'b0;
reset_pending <= 1'b0;
write_buffer_flush_pending <= 1'b0;
write_modem_status_pending <= 1'b0;
modem_status_counter <= 5'd0;
last_reset_status <= 1'b0;
reset_reply <= 1'b0;
phase <= 4'b0001;
state <= STATE_IDLE;
end else begin
if (write_buffer_flush) begin
write_buffer_flush_pending <= 1'b1;
end end
if (reset) begin
reset_pending <= 1'b0;
last_reset_status <= 1'b0;
modem_status_counter <= 5'd0;
write_modem_status_pending <= 1'b0;
write_buffer_flush_pending <= 1'b0;
end else begin
if (reset_ack) begin if (reset_ack) begin
reset_pending <= 1'b0; reset_pending <= 1'b0;
write_modem_status_pending <= 1'b1; write_modem_status_pending <= 1'b1;
reset_reply <= 1'b1; reset_reply <= 1'b1;
end end
if (modem_status_read) begin if (write_buffer_flush) begin
last_reset_status <= usb_miosi[0]; write_buffer_flush_pending <= 1'b1;
if (!last_reset_status && usb_miosi[0]) begin end
if (state == STATE_IDLE) begin
modem_status_counter <= modem_status_counter + 1'd1;
end
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
if (cmd == CMD_READ_MODEM_STATUS) begin
last_reset_status <= ft_miosi_in[0];
if (!last_reset_status && ft_miosi_in[0]) begin
reset_pending <= 1'b1; reset_pending <= 1'b1;
end end
if (last_reset_status && !usb_miosi[0]) begin if (last_reset_status && !ft_miosi_in[0]) begin
write_modem_status_pending <= 1'b1; write_modem_status_pending <= 1'b1;
reset_reply <= 1'b0; reset_reply <= 1'b0;
end end
end end
if (cmd == CMD_WRITE_MODEM_STATUS) begin
write_modem_status_pending <= 1'b0;
end
if (cmd == CMD_WRITE_BUFFER_FLUSH) begin
write_buffer_flush_pending <= 1'b0;
end
end
end
end
always_comb begin
ft_clk = 1'b0;
ft_cs = 1'b1;
ft_miosi_out = 8'hFF;
ft_oe = 1'b0;
if (state == STATE_SELECT) begin
ft_cs = 1'b0;
end
if (state == STATE_COMMAND) begin
if (phase[0] || phase[1]) begin
ft_clk = 1'b1;
end
ft_cs = 1'b0;
ft_miosi_out = cmd;
ft_oe = 1'b1;
end
if (state == STATE_STATUS) begin
if (phase[0] || phase[1]) begin
ft_clk = 1'b1;
end
ft_cs = 1'b0;
end
if (state == STATE_DATA) begin
ft_cs = 1'b0;
if (phase[0] || phase[1]) begin
ft_clk = 1'b1;
end
if (cmd == CMD_WRITE) begin
ft_miosi_out = tx_rdata;
ft_oe = 1'b1;
end
if (cmd == CMD_WRITE_MODEM_STATUS) begin
ft_miosi_out = {2'b00, reset_reply, 5'b00000};
ft_oe = 1'b1;
end
end
end
always_comb begin
rx_write = 1'b0;
tx_read = 1'b0;
rx_wdata = ft_miosi_in;
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
if (cmd == CMD_WRITE) begin
tx_read = 1'b1;
end
if (cmd == CMD_READ) begin
rx_write = 1'b1;
end
end
end
always_comb begin
next_state = state;
next_cmd = cmd;
if (reset) begin
next_state = STATE_IDLE;
end else begin
case (state) case (state)
STATE_IDLE: begin STATE_IDLE: begin
usb_cs <= 1'b0;
state <= STATE_SELECT;
if (write_modem_status_pending) begin if (write_modem_status_pending) begin
usb_cmd <= CMD_WRITE_MODEM_STATUS; next_state = STATE_SELECT;
next_cmd = CMD_WRITE_MODEM_STATUS;
end else if (&modem_status_counter) begin end else if (&modem_status_counter) begin
usb_cmd <= CMD_READ_MODEM_STATUS; next_state = STATE_SELECT;
next_cmd = CMD_READ_MODEM_STATUS;
end else if (!tx_empty) begin end else if (!tx_empty) begin
usb_cmd <= CMD_WRITE; next_state = STATE_SELECT;
next_cmd = CMD_WRITE;
end else if (write_buffer_flush_pending) begin end else if (write_buffer_flush_pending) begin
usb_cmd <= CMD_WRITE_BUFFER_FLUSH; next_state = STATE_SELECT;
next_cmd = CMD_WRITE_BUFFER_FLUSH;
end else if (!rx_full) begin end else if (!rx_full) begin
usb_cmd <= CMD_READ; next_state = STATE_SELECT;
end else begin next_cmd = CMD_READ;
usb_cs <= 1'b1;
modem_status_counter <= modem_status_counter + 1'd1;
state <= STATE_IDLE;
end end
end end
STATE_SELECT: begin STATE_SELECT: begin
phase <= 4'b0001; if (phase[3]) begin
state <= STATE_COMMAND; next_state = STATE_COMMAND;
end
end end
STATE_COMMAND: begin STATE_COMMAND: begin
if (phase[0]) begin if (phase[3]) begin
usb_clk <= 1'b1; next_state = STATE_STATUS;
usb_miosi_oe <= 1'b1;
end else if (phase[2]) begin
usb_clk <= 1'b0;
end else if (phase[3]) begin
state <= STATE_STATUS;
end end
end end
STATE_STATUS: begin STATE_STATUS: begin
if (phase[0]) begin if (phase[3]) begin
usb_clk <= 1'b1; if (ft_miso) begin
usb_miosi_oe <= 1'b0; next_state = STATE_DESELECT;
end else if (phase[2]) begin end else begin
usb_clk <= 1'b0; next_state = STATE_DATA;
end else if (phase[3]) begin end
state <= STATE_DATA;
end end
end end
STATE_DATA: begin STATE_DATA: begin
if (phase[0]) begin if (phase[3]) begin
usb_clk <= 1'b1; if (ft_miso) begin
usb_miosi_oe <= (usb_cmd == CMD_WRITE) || (usb_cmd == CMD_WRITE_MODEM_STATUS); next_state = STATE_DESELECT;
end else if (phase[2]) begin end else if (cmd == CMD_WRITE) begin
usb_clk <= 1'b0;
end else if (phase[3]) begin
if (usb_miso) begin
state <= STATE_DESELECT;
end else if (usb_cmd == CMD_WRITE) begin
tx_read <= 1'b1;
if (tx_almost_empty) begin if (tx_almost_empty) begin
state <= STATE_DESELECT; next_state = STATE_DESELECT;
end end
end else if (usb_cmd == CMD_READ) begin end else if (cmd == CMD_READ) begin
rx_write <= 1'b1;
if (rx_almost_full) begin if (rx_almost_full) begin
state <= STATE_DESELECT; next_state = STATE_DESELECT;
end end
end else if (usb_cmd == CMD_READ_MODEM_STATUS) begin end else begin
modem_status_read <= 1'b1; next_state = STATE_DESELECT;
state <= STATE_DESELECT;
end else if (usb_cmd == CMD_WRITE_MODEM_STATUS) begin
write_modem_status_pending <= 1'b0;
state <= STATE_DESELECT;
end else if (usb_cmd == CMD_WRITE_BUFFER_FLUSH) begin
write_buffer_flush_pending <= 1'b0;
state <= STATE_DESELECT;
end end
end end
end end
STATE_DESELECT: begin STATE_DESELECT: begin
usb_cs <= 1'b1;
usb_miosi_oe <= 1'b0;
if (phase[1]) begin if (phase[1]) begin
modem_status_counter <= modem_status_counter + 1'd1; next_state = STATE_IDLE;
state <= STATE_IDLE;
end end
end end
default: begin
next_state = STATE_IDLE;
end
endcase endcase
end end
end end

View File

@ -157,9 +157,9 @@ class SC64:
self.__usb.close() self.__usb.close()
for p in ports: for p in ports:
if (p.vid == 0x0403 and p.pid == 0x6014 and p.serial_number.startswith("SC")): if (p.vid == 0x0403 and p.pid == 0x6014 and p.serial_number.startswith("SC64")):
try: try:
self.__usb = Serial(p.device, timeout=0.5, write_timeout=0.5) self.__usb = Serial(p.device, timeout=1.0, write_timeout=1.0)
self.reset_link() self.reset_link()
self.__probe_device() self.__probe_device()
except (SerialException, SC64Exception): except (SerialException, SC64Exception):