// --------------------------------------------------------------------------- // dshot600_tx_x4.sv — QX-250 FPGA block B1 (4-channel wrapper) // FPGA-QX250-001 · drives DSHOT_M1..M4 (EAD-QX250-001 SIG sheet) // // Four dshot600_tx cores sharing one `send` strobe so all four ESC frames are // emitted phase-aligned — the mixer's four motor commands leave the FPGA on the // same edge, which is the determinism guarantee that justifies B1 in hardware. // --------------------------------------------------------------------------- `timescale 1ns/1ps `default_nettype none module dshot600_tx_x4 #( parameter int CLK_HZ = 48_000_000, parameter bit BIDIR = 1'b0 ) ( input wire clk, input wire rst_n, input wire [10:0] throttle [4], // per-channel throttle (M1..M4) input wire [3:0] telemetry, // per-channel telemetry-request bit input wire send, // shared: launch all four aligned output wire busy, // high while any channel is transmitting output wire done, // 1-cycle pulse when all four complete output wire [3:0] dshot_out // DSHOT_M1..M4 ); wire [3:0] ch_busy; wire [3:0] ch_done; genvar i; generate for (i = 0; i < 4; i++) begin : g_ch dshot600_tx #(.CLK_HZ(CLK_HZ), .BIDIR(BIDIR)) u_ch ( .clk (clk), .rst_n (rst_n), .throttle (throttle[i]), .telemetry (telemetry[i]), .send (send), .busy (ch_busy[i]), .done (ch_done[i]), .dshot_out (dshot_out[i]) ); end endgenerate // Channels share `send` and identical timing, so they finish on the same // cycle: OR the busys, AND the dones. assign busy = |ch_busy; assign done = &ch_done; endmodule `default_nettype wire