`timescale 1ns / 1ns // * Engineer: // * *************************************************** * // * ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗ * // * ╚══███╔╝██╔═══██╗██╔══██╗██╔═══██╗██╔════╝ ██║ ██║ * // * ███╔╝ ██║ ██║██████╔╝██║ ██║██║ ███╗███████║ * // * ███╔╝ ██║ ██║██╔══██╗██║ ██║██║ ██║██╔══██║ * // * ███████╗╚██████╔╝██║ ██║╚██████╔╝╚██████╔╝██║ ██║ * // * ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ * // * *************************************************** * // * Create Date: 2024/04/08 // * Update Date: 2024/05/17 // ! PLEASE MAKE SURE THE PARAMETER ARE VALID // ! WHEN U INSTANTIATE THIS MODULE module tdma ( input clk, input rst, // PHY parameter input flag_frame_sync, // general parameter, update only once input wire [23:0] tdma_slot_len, input wire [23:0] tdma_tic_2_ps, input wire [ 7:0] tdma_slot_num, input wire [23:0] tdma_frame_sync_tic, input wire [ 7:0] local_id, // ID number for this device // update while received valid input wire recevied_cur_slot_id_valid, // recevied ID number of the frame input wire [ 7:0] recevied_cur_slot_id, output intr_2ps, output tx_start, output reg rx_rst ); // ******** Wire & Reg ******** reg flag_next_slot_is_tx_slot; reg [23:0] cnt_tdma_slot_len; reg [ 7:0] cur_slot_id; wire flag_end_of_one_slot; // the last period of the slot wire [23:0] tdma_tic_frame_sync_vio; // fsm localparam S_IDLE = 0; localparam S_RX = 1; localparam S_TX = 2; reg [1:0] cs = 0; reg [1:0] ns = 0; // ******** Assingment ******** assign flag_end_of_one_slot = (cnt_tdma_slot_len == tdma_slot_len - 1); assign tx_start = (cs == S_TX) & (cnt_tdma_slot_len == 16'd10); assign intr_2ps = flag_next_slot_is_tx_slot & (cnt_tdma_slot_len == tdma_tic_2_ps - 1); // ******** Logic Block ******** // fsm always @(posedge clk) begin if (rst) begin cs <= S_IDLE; end else begin cs <= ns; end end // conditional transition always @(*) begin ns = cs; case (cs) S_IDLE: begin // if this device is master node, ps should first send one packet to the fifo if (local_id == 1) begin ns = S_TX; end else if (recevied_cur_slot_id_valid) begin ns = S_RX; end end S_RX: begin if (flag_next_slot_is_tx_slot && flag_end_of_one_slot) begin ns = S_TX; end end S_TX: begin if (~flag_next_slot_is_tx_slot && flag_end_of_one_slot) begin ns = S_RX; end end default: begin ns = S_IDLE; end endcase end always @(posedge clk) begin if (rst) begin cnt_tdma_slot_len <= 0; end else if (flag_frame_sync) begin cnt_tdma_slot_len <= tdma_frame_sync_tic; end else begin if (flag_end_of_one_slot) begin cnt_tdma_slot_len <= 0; end else begin cnt_tdma_slot_len <= cnt_tdma_slot_len + 1; end end end always @(*) begin if (cs == S_TX || cnt_tdma_slot_len <= 10) begin rx_rst <= 1; end else begin rx_rst <= 0; end end always @(posedge clk) begin if (cs == S_IDLE) begin if (ns == S_TX) begin // indicating master node cur_slot_id <= 1; end else if (recevied_cur_slot_id_valid) begin // from ps update, first sync, indicating slave cur_slot_id <= recevied_cur_slot_id; end else begin cur_slot_id <= 0; end end else begin if (recevied_cur_slot_id_valid) begin // from ps update cur_slot_id <= recevied_cur_slot_id; end else if (flag_end_of_one_slot) begin // at the changing moment if (cur_slot_id == tdma_slot_num) begin cur_slot_id <= 1; end else begin cur_slot_id <= cur_slot_id + 1; end end end end always @(posedge clk) begin if (local_id == 1) begin flag_next_slot_is_tx_slot <= (cur_slot_id == tdma_slot_num); end else begin flag_next_slot_is_tx_slot <= (cur_slot_id + 1 == local_id); end end // ******** Inst ******** // ******** Debug ******** vio_tdma u_vio_tdma ( .clk (clk), .probe_in0(tdma_slot_len), .probe_in1(tdma_tic_2_ps), .probe_in2(tdma_slot_num), .probe_in3(local_id), .probe_in4(tdma_frame_sync_tic) ); ila_mac_layer u_ila_mac_layer ( .clk (clk), .probe0(cnt_tdma_slot_len), // width: 24 .probe1(tx_start), // width: 1 .probe2(rx_rst), // width: 1 .probe3(cur_slot_id), // width: 8 .probe4(intr_2ps), // width: 1 .probe5(flag_frame_sync), // width: 1 .probe6(recevied_cur_slot_id), // width: 8 .probe7(recevied_cur_slot_id_valid) // width: 1 ); endmodule