190 lines
6.1 KiB
Verilog
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
|