Files
MM7020/hdl/tdma.v
T
2024-10-12 11:02:35 +08:00

190 lines
6.1 KiB
Verilog

`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