|
|
@@ -1,472 +0,0 @@
|
|
|
-`timescale 1ns/1ps
|
|
|
-`include "trace_build_id.vh"
|
|
|
-
|
|
|
-// -----------------------------------------------------------------------------
|
|
|
-// Single-CP2102 motor HIL + Trace top-level.
|
|
|
-//
|
|
|
-// One UART carries BOTH:
|
|
|
-// * control/HIL packets while the virtual motor is running
|
|
|
-// * Trace packets after the motor test finishes
|
|
|
-//
|
|
|
-// The PC program is the virtual motor and Trace receiver at the same time.
|
|
|
-// -----------------------------------------------------------------------------
|
|
|
-module top_ef2l45_motor_hil_trace #(
|
|
|
- parameter integer CLK_HZ = 25000000,
|
|
|
- parameter integer BAUD = 115200,
|
|
|
- parameter integer TRACE_DEPTH = 1024,
|
|
|
- parameter integer TRACE_ADDR_W = 10,
|
|
|
- parameter integer STEP_MS = 10,
|
|
|
- parameter integer FEEDBACK_TIMEOUT_CYCLES = 50000000,
|
|
|
- parameter integer LED_HOLD_CYCLES = 6250000
|
|
|
-)(
|
|
|
- input wire sys_clk,
|
|
|
- input wire reset_n,
|
|
|
- output wire uart_tx,
|
|
|
- input wire uart_rx,
|
|
|
-
|
|
|
- output wire led_heartbeat_n,
|
|
|
- output wire led_reset_n,
|
|
|
- output wire led_activity_n,
|
|
|
- output wire led_tx_n,
|
|
|
- output wire led_error_n
|
|
|
-);
|
|
|
- localparam [7:0] PKT_STATUS = 8'h81;
|
|
|
- localparam [7:0] PKT_TRACE = 8'h82;
|
|
|
- localparam [7:0] PKT_SUMMARY = 8'h83;
|
|
|
- localparam [7:0] PKT_MOTOR_CMD = 8'h90;
|
|
|
- localparam [15:0] STATUS_EVENT_ID = 16'hB17D;
|
|
|
-
|
|
|
- localparam [3:0] T_IDLE = 4'd0;
|
|
|
- localparam [3:0] T_SEND_STATUS = 4'd1;
|
|
|
- localparam [3:0] T_WAIT_STATUS = 4'd2;
|
|
|
- localparam [3:0] T_SEND_MOTOR = 4'd3;
|
|
|
- localparam [3:0] T_WAIT_MOTOR = 4'd4;
|
|
|
- localparam [3:0] T_WAIT_FB = 4'd5;
|
|
|
- localparam [3:0] T_APPLY_FB = 4'd6;
|
|
|
- localparam [3:0] T_CHECK = 4'd7;
|
|
|
- localparam [3:0] T_PREP = 4'd8;
|
|
|
- localparam [3:0] T_READ = 4'd9;
|
|
|
- localparam [3:0] T_SEND_TRACE = 4'd10;
|
|
|
- localparam [3:0] T_WAIT_TRACE = 4'd11;
|
|
|
- localparam [3:0] T_SEND_SUMMARY = 4'd12;
|
|
|
- localparam [3:0] T_WAIT_SUMMARY = 4'd13;
|
|
|
-
|
|
|
- wire rst_n;
|
|
|
- wire [7:0] rx_data;
|
|
|
- wire rx_valid;
|
|
|
- wire rx_framing_error;
|
|
|
-
|
|
|
- wire fb_packet_valid;
|
|
|
- wire [15:0] fb_packet_seq;
|
|
|
- wire [15:0] fb_packet_flags;
|
|
|
- wire [31:0] fb_packet_timestamp;
|
|
|
- wire [15:0] fb_packet_rpm;
|
|
|
- wire [15:0] fb_packet_current_ma;
|
|
|
- wire fb_crc_error;
|
|
|
-
|
|
|
- reg motor_start;
|
|
|
- reg motor_feedback_valid;
|
|
|
- reg [15:0] motor_feedback_rpm;
|
|
|
- reg [15:0] motor_feedback_current_ma;
|
|
|
- reg motor_feedback_fault;
|
|
|
- reg motor_feedback_encoder_ok;
|
|
|
- reg [15:0] motor_feedback_time_ms;
|
|
|
-
|
|
|
- wire motor_busy;
|
|
|
- wire motor_done;
|
|
|
- wire [6:0] motor_pwm;
|
|
|
- wire motor_enable;
|
|
|
- wire motor_direction;
|
|
|
- wire [15:0] motor_state_id;
|
|
|
- wire [7:0] motor_fault_code;
|
|
|
- wire motor_trace_valid;
|
|
|
- wire [15:0] motor_trace_id;
|
|
|
- wire [15:0] motor_trace_timestamp;
|
|
|
- wire [31:0] motor_trace_data;
|
|
|
-
|
|
|
- reg capture_reset;
|
|
|
- wire [15:0] captured_count;
|
|
|
- wire [31:0] drop_count;
|
|
|
- wire overflow;
|
|
|
- reg rd_en;
|
|
|
- reg [TRACE_ADDR_W-1:0] rd_addr;
|
|
|
- wire [63:0] rd_data;
|
|
|
-
|
|
|
- reg pkt_send;
|
|
|
- reg [7:0] pkt_type;
|
|
|
- reg [15:0] pkt_seq;
|
|
|
- reg [15:0] pkt_event_id;
|
|
|
- reg [31:0] pkt_timestamp;
|
|
|
- reg [31:0] pkt_data;
|
|
|
- wire pkt_busy;
|
|
|
- wire pkt_done;
|
|
|
-
|
|
|
- reg [3:0] top_state;
|
|
|
- reg [15:0] hil_seq;
|
|
|
- reg [31:0] sim_time_ms;
|
|
|
- reg [31:0] feedback_timeout_counter;
|
|
|
- reg [15:0] total_to_dump;
|
|
|
- reg [15:0] dump_index;
|
|
|
- reg [31:0] sim_time_latched;
|
|
|
- reg [31:0] drop_count_latched;
|
|
|
- reg hil_link_error;
|
|
|
-
|
|
|
- // Latch one validated feedback packet before applying it to the controller.
|
|
|
- reg [15:0] fb_seq_l;
|
|
|
- reg [15:0] fb_flags_l;
|
|
|
- reg [31:0] fb_time_l;
|
|
|
- reg [15:0] fb_rpm_l;
|
|
|
- reg [15:0] fb_current_l;
|
|
|
-
|
|
|
- reg [31:0] heartbeat_counter;
|
|
|
- reg heartbeat_phase;
|
|
|
- reg [31:0] activity_hold_counter;
|
|
|
- reg [31:0] tx_hold_counter;
|
|
|
- reg error_latched;
|
|
|
-
|
|
|
- wire start_cmd = rx_valid && (rx_data == 8'h53) && (top_state == T_IDLE); // 'S'
|
|
|
- wire ping_cmd = rx_valid && (rx_data == 8'h50) && (top_state == T_IDLE); // 'P'
|
|
|
-
|
|
|
- wire transaction_busy = (top_state != T_IDLE) &&
|
|
|
- (top_state != T_SEND_STATUS) &&
|
|
|
- (top_state != T_WAIT_STATUS);
|
|
|
-
|
|
|
- reset_sync u_reset_sync (
|
|
|
- .clk(sys_clk),
|
|
|
- .reset_n_ext(reset_n),
|
|
|
- .reset_n(rst_n)
|
|
|
- );
|
|
|
-
|
|
|
- uart_rx #(
|
|
|
- .CLK_HZ(CLK_HZ),
|
|
|
- .BAUD(BAUD)
|
|
|
- ) u_uart_rx (
|
|
|
- .clk(sys_clk),
|
|
|
- .reset_n(rst_n),
|
|
|
- .rx(uart_rx),
|
|
|
- .data(rx_data),
|
|
|
- .valid(rx_valid),
|
|
|
- .framing_error(rx_framing_error)
|
|
|
- );
|
|
|
-
|
|
|
- motor_feedback_rx u_feedback_rx (
|
|
|
- .clk(sys_clk),
|
|
|
- .reset_n(rst_n),
|
|
|
- .rx_data(rx_data),
|
|
|
- .rx_valid(rx_valid),
|
|
|
- .feedback_valid(fb_packet_valid),
|
|
|
- .feedback_seq(fb_packet_seq),
|
|
|
- .feedback_flags(fb_packet_flags),
|
|
|
- .feedback_timestamp(fb_packet_timestamp),
|
|
|
- .feedback_rpm(fb_packet_rpm),
|
|
|
- .feedback_current_ma(fb_packet_current_ma),
|
|
|
- .crc_error(fb_crc_error)
|
|
|
- );
|
|
|
-
|
|
|
- motor_controller_hil u_motor_controller (
|
|
|
- .clk(sys_clk),
|
|
|
- .reset_n(rst_n),
|
|
|
- .start(motor_start),
|
|
|
- .feedback_valid(motor_feedback_valid),
|
|
|
- .feedback_rpm(motor_feedback_rpm),
|
|
|
- .feedback_current_ma(motor_feedback_current_ma),
|
|
|
- .feedback_fault(motor_feedback_fault),
|
|
|
- .feedback_encoder_ok(motor_feedback_encoder_ok),
|
|
|
- .feedback_time_ms(motor_feedback_time_ms),
|
|
|
- .busy(motor_busy),
|
|
|
- .done(motor_done),
|
|
|
- .pwm_duty(motor_pwm),
|
|
|
- .motor_enable(motor_enable),
|
|
|
- .direction(motor_direction),
|
|
|
- .state_id(motor_state_id),
|
|
|
- .fault_code(motor_fault_code),
|
|
|
- .trace_valid(motor_trace_valid),
|
|
|
- .trace_id(motor_trace_id),
|
|
|
- .trace_timestamp(motor_trace_timestamp),
|
|
|
- .trace_data(motor_trace_data)
|
|
|
- );
|
|
|
-
|
|
|
- trace_capture_ram #(
|
|
|
- .TRACE_DEPTH(TRACE_DEPTH),
|
|
|
- .TRACE_ADDR_W(TRACE_ADDR_W)
|
|
|
- ) u_trace_ram (
|
|
|
- .clk(sys_clk),
|
|
|
- .reset_n(rst_n),
|
|
|
- .capture_reset(capture_reset),
|
|
|
- .trace_valid(motor_trace_valid && (top_state == T_APPLY_FB)),
|
|
|
- .trace_id(motor_trace_id),
|
|
|
- .trace_timestamp(motor_trace_timestamp),
|
|
|
- .trace_data(motor_trace_data),
|
|
|
- .captured_count(captured_count),
|
|
|
- .drop_count(drop_count),
|
|
|
- .overflow(overflow),
|
|
|
- .rd_en(rd_en),
|
|
|
- .rd_addr(rd_addr),
|
|
|
- .rd_data(rd_data)
|
|
|
- );
|
|
|
-
|
|
|
- trace_packet_tx #(
|
|
|
- .CLK_HZ(CLK_HZ),
|
|
|
- .BAUD(BAUD)
|
|
|
- ) u_packet_tx (
|
|
|
- .clk(sys_clk),
|
|
|
- .reset_n(rst_n),
|
|
|
- .send(pkt_send),
|
|
|
- .pkt_type(pkt_type),
|
|
|
- .seq(pkt_seq),
|
|
|
- .event_id(pkt_event_id),
|
|
|
- .timestamp(pkt_timestamp),
|
|
|
- .data(pkt_data),
|
|
|
- .uart_tx_o(uart_tx),
|
|
|
- .busy(pkt_busy),
|
|
|
- .done(pkt_done)
|
|
|
- );
|
|
|
-
|
|
|
- assign led_heartbeat_n = heartbeat_phase ? 1'b0 : 1'b1;
|
|
|
- assign led_reset_n = reset_n;
|
|
|
- assign led_activity_n = (activity_hold_counter != 0) ? 1'b0 : 1'b1;
|
|
|
- assign led_tx_n = (tx_hold_counter != 0) ? 1'b0 : 1'b1;
|
|
|
- assign led_error_n = error_latched ? 1'b0 : 1'b1;
|
|
|
-
|
|
|
- always @(posedge sys_clk or negedge rst_n) begin
|
|
|
- if (!rst_n) begin
|
|
|
- heartbeat_counter <= 32'd0;
|
|
|
- heartbeat_phase <= 1'b0;
|
|
|
- activity_hold_counter <= 32'd0;
|
|
|
- tx_hold_counter <= 32'd0;
|
|
|
- error_latched <= 1'b0;
|
|
|
- end else begin
|
|
|
- if (heartbeat_counter >= (CLK_HZ / 2) - 1) begin
|
|
|
- heartbeat_counter <= 32'd0;
|
|
|
- heartbeat_phase <= ~heartbeat_phase;
|
|
|
- end else begin
|
|
|
- heartbeat_counter <= heartbeat_counter + 1'b1;
|
|
|
- end
|
|
|
-
|
|
|
- if (start_cmd || transaction_busy)
|
|
|
- activity_hold_counter <= LED_HOLD_CYCLES;
|
|
|
- else if (activity_hold_counter != 0)
|
|
|
- activity_hold_counter <= activity_hold_counter - 1'b1;
|
|
|
-
|
|
|
- if (pkt_busy || pkt_send)
|
|
|
- tx_hold_counter <= LED_HOLD_CYCLES;
|
|
|
- else if (tx_hold_counter != 0)
|
|
|
- tx_hold_counter <= tx_hold_counter - 1'b1;
|
|
|
-
|
|
|
- if (start_cmd)
|
|
|
- error_latched <= 1'b0;
|
|
|
- if (rx_framing_error || fb_crc_error || overflow || hil_link_error || (motor_fault_code != 0))
|
|
|
- error_latched <= 1'b1;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- // Combinational control for one-cycle pulses and the shared packet transmitter.
|
|
|
- always @(*) begin
|
|
|
- motor_start = 1'b0;
|
|
|
- motor_feedback_valid = 1'b0;
|
|
|
- motor_feedback_rpm = fb_rpm_l;
|
|
|
- motor_feedback_current_ma = fb_current_l;
|
|
|
- motor_feedback_fault = fb_flags_l[0];
|
|
|
- motor_feedback_encoder_ok = fb_flags_l[1];
|
|
|
- motor_feedback_time_ms = fb_time_l[15:0];
|
|
|
-
|
|
|
- capture_reset = 1'b0;
|
|
|
- rd_en = 1'b0;
|
|
|
- rd_addr = dump_index[TRACE_ADDR_W-1:0];
|
|
|
-
|
|
|
- pkt_send = 1'b0;
|
|
|
- pkt_type = PKT_TRACE;
|
|
|
- pkt_seq = dump_index;
|
|
|
- pkt_event_id = rd_data[47:32];
|
|
|
- pkt_timestamp = {16'd0, rd_data[63:48]};
|
|
|
- pkt_data = rd_data[31:0];
|
|
|
-
|
|
|
- case (top_state)
|
|
|
- T_IDLE: begin
|
|
|
- if (start_cmd) begin
|
|
|
- capture_reset = 1'b1;
|
|
|
- motor_start = 1'b1;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_STATUS: begin
|
|
|
- pkt_type = PKT_STATUS;
|
|
|
- pkt_seq = 16'd0;
|
|
|
- pkt_event_id = STATUS_EVENT_ID;
|
|
|
- pkt_timestamp = 32'd0;
|
|
|
- pkt_data = `TRACE_BUILD_ID;
|
|
|
- if (!pkt_busy)
|
|
|
- pkt_send = 1'b1;
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_MOTOR: begin
|
|
|
- pkt_type = PKT_MOTOR_CMD;
|
|
|
- pkt_seq = hil_seq;
|
|
|
- pkt_event_id = motor_state_id;
|
|
|
- pkt_timestamp = sim_time_ms;
|
|
|
- pkt_data = {1'b0, motor_pwm, motor_enable, motor_direction, 22'd0};
|
|
|
- if (!pkt_busy)
|
|
|
- pkt_send = 1'b1;
|
|
|
- end
|
|
|
-
|
|
|
- T_APPLY_FB: begin
|
|
|
- motor_feedback_valid = 1'b1;
|
|
|
- end
|
|
|
-
|
|
|
- T_READ: begin
|
|
|
- rd_en = 1'b1;
|
|
|
- rd_addr = dump_index[TRACE_ADDR_W-1:0];
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_TRACE: begin
|
|
|
- if (!pkt_busy)
|
|
|
- pkt_send = 1'b1;
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_SUMMARY: begin
|
|
|
- pkt_type = PKT_SUMMARY;
|
|
|
- pkt_seq = total_to_dump;
|
|
|
- pkt_event_id = hil_link_error ? 16'hFFFE : 16'hFFFF;
|
|
|
- pkt_timestamp = sim_time_latched;
|
|
|
- pkt_data = drop_count_latched;
|
|
|
- if (!pkt_busy)
|
|
|
- pkt_send = 1'b1;
|
|
|
- end
|
|
|
-
|
|
|
- default: begin end
|
|
|
- endcase
|
|
|
- end
|
|
|
-
|
|
|
- always @(posedge sys_clk or negedge rst_n) begin
|
|
|
- if (!rst_n) begin
|
|
|
- top_state <= T_IDLE;
|
|
|
- hil_seq <= 16'd0;
|
|
|
- sim_time_ms <= 32'd0;
|
|
|
- feedback_timeout_counter <= 32'd0;
|
|
|
- total_to_dump <= 16'd0;
|
|
|
- dump_index <= 16'd0;
|
|
|
- sim_time_latched <= 32'd0;
|
|
|
- drop_count_latched <= 32'd0;
|
|
|
- hil_link_error <= 1'b0;
|
|
|
- fb_seq_l <= 16'd0;
|
|
|
- fb_flags_l <= 16'd0;
|
|
|
- fb_time_l <= 32'd0;
|
|
|
- fb_rpm_l <= 16'd0;
|
|
|
- fb_current_l <= 16'd0;
|
|
|
- end else begin
|
|
|
- case (top_state)
|
|
|
- T_IDLE: begin
|
|
|
- hil_seq <= 16'd0;
|
|
|
- sim_time_ms <= 32'd0;
|
|
|
- feedback_timeout_counter <= 32'd0;
|
|
|
- dump_index <= 16'd0;
|
|
|
- if (start_cmd) begin
|
|
|
- hil_link_error <= 1'b0;
|
|
|
- top_state <= T_SEND_MOTOR;
|
|
|
- end else if (ping_cmd) begin
|
|
|
- top_state <= T_SEND_STATUS;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_STATUS: begin
|
|
|
- if (!pkt_busy)
|
|
|
- top_state <= T_WAIT_STATUS;
|
|
|
- end
|
|
|
-
|
|
|
- T_WAIT_STATUS: begin
|
|
|
- if (pkt_done)
|
|
|
- top_state <= T_IDLE;
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_MOTOR: begin
|
|
|
- if (!pkt_busy)
|
|
|
- top_state <= T_WAIT_MOTOR;
|
|
|
- end
|
|
|
-
|
|
|
- T_WAIT_MOTOR: begin
|
|
|
- if (pkt_done) begin
|
|
|
- feedback_timeout_counter <= 32'd0;
|
|
|
- top_state <= T_WAIT_FB;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- T_WAIT_FB: begin
|
|
|
- if (fb_packet_valid) begin
|
|
|
- if (fb_packet_seq == hil_seq) begin
|
|
|
- fb_seq_l <= fb_packet_seq;
|
|
|
- fb_flags_l <= fb_packet_flags;
|
|
|
- fb_time_l <= fb_packet_timestamp;
|
|
|
- fb_rpm_l <= fb_packet_rpm;
|
|
|
- fb_current_l <= fb_packet_current_ma;
|
|
|
- top_state <= T_APPLY_FB;
|
|
|
- end else begin
|
|
|
- hil_link_error <= 1'b1;
|
|
|
- top_state <= T_PREP;
|
|
|
- end
|
|
|
- end else if (feedback_timeout_counter >= FEEDBACK_TIMEOUT_CYCLES - 1) begin
|
|
|
- hil_link_error <= 1'b1;
|
|
|
- top_state <= T_PREP;
|
|
|
- end else begin
|
|
|
- feedback_timeout_counter <= feedback_timeout_counter + 1'b1;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- T_APPLY_FB: begin
|
|
|
- top_state <= T_CHECK;
|
|
|
- end
|
|
|
-
|
|
|
- T_CHECK: begin
|
|
|
- hil_seq <= hil_seq + 1'b1;
|
|
|
- sim_time_ms <= sim_time_ms + STEP_MS;
|
|
|
- if (motor_done)
|
|
|
- top_state <= T_PREP;
|
|
|
- else
|
|
|
- top_state <= T_SEND_MOTOR;
|
|
|
- end
|
|
|
-
|
|
|
- T_PREP: begin
|
|
|
- total_to_dump <= captured_count;
|
|
|
- sim_time_latched <= sim_time_ms;
|
|
|
- drop_count_latched <= drop_count;
|
|
|
- dump_index <= 16'd0;
|
|
|
- if (captured_count == 0)
|
|
|
- top_state <= T_SEND_SUMMARY;
|
|
|
- else
|
|
|
- top_state <= T_READ;
|
|
|
- end
|
|
|
-
|
|
|
- T_READ: begin
|
|
|
- top_state <= T_SEND_TRACE;
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_TRACE: begin
|
|
|
- if (!pkt_busy)
|
|
|
- top_state <= T_WAIT_TRACE;
|
|
|
- end
|
|
|
-
|
|
|
- T_WAIT_TRACE: begin
|
|
|
- if (pkt_done) begin
|
|
|
- if ((dump_index + 1'b1) >= total_to_dump) begin
|
|
|
- top_state <= T_SEND_SUMMARY;
|
|
|
- end else begin
|
|
|
- dump_index <= dump_index + 1'b1;
|
|
|
- top_state <= T_READ;
|
|
|
- end
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- T_SEND_SUMMARY: begin
|
|
|
- if (!pkt_busy)
|
|
|
- top_state <= T_WAIT_SUMMARY;
|
|
|
- end
|
|
|
-
|
|
|
- T_WAIT_SUMMARY: begin
|
|
|
- if (pkt_done)
|
|
|
- top_state <= T_IDLE;
|
|
|
- end
|
|
|
-
|
|
|
- default: top_state <= T_IDLE;
|
|
|
- endcase
|
|
|
- end
|
|
|
- end
|
|
|
-endmodule
|