`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2022/09/01 14:39:50 // Design Name: // Module Name: antenna_interface // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module antenna_interface #( parameter [15:0] FRAME_HEAD = 16'hCCCC, parameter [15:0] FRAME_TAIL = 16'hF0F0, parameter [15:0] FRAME_LENGTH = 16'h0100,//include frame_head and frame_tail parameter [15:0] REST_LENGTH = 16'h0014, parameter [15:0] FRAME_MAX_LENGTH = 16'h0200, parameter [15:0] REST_MAX_LENGTH = 16'h0020 ) ( input clk_in , input data_in , input tr_in , input dary_in , input rst , output reg ant_clk , output en_out , input clk_out , output data_out , output tr_out , output dary_out , //debug output reg [15:0] debug_freq , output reg debug_freq_change , output [63:0] debug_tr_count ); reg fifo_data_in ; wire fifo_data_out ; reg fifo_wr_en ; reg fifo_rd_en ; wire fifo_full ; wire fifo_empty ; wire valid ; fifo_en_creat u_fifo_en_creat ( .wr_clk(clk_in), // input wire wr_clk .wr_rst(rst), // input wire wr_rst .rd_clk(clk_out), // input wire rd_clk .rd_rst(rst), // input wire rd_rst .din(fifo_data_in), // input wire [0 : 0] din .wr_en(fifo_wr_en), // input wire wr_en .rd_en(fifo_rd_en), // input wire rd_en .dout(fifo_data_out), // output wire [0 : 0] dout .full(fifo_full), // output wire full .empty(fifo_empty), // output wire empty .valid(valid) // output wire valid ); reg [3:0] rx_state_next; reg [3:0] rx_state; reg [3:0] tx_state_next; reg [3:0] tx_state; localparam WAIT = 4'd0; localparam RECV = 4'd1; localparam SEND = 4'd2; localparam REST = 4'd3; //1 to 8 reg [16:0] data_in_9; always @ ( posedge clk_in or posedge rst) begin if ( rst ) begin data_in_9 <= 17'd0; end else begin data_in_9 <= {data_in_9[15:0],data_in}; end end //cnt reg [15:0] rx_bitcnt; always @(posedge clk_in or posedge rst) begin if(rst) begin rx_bitcnt[15:0] <= 16'd0; end else if(rx_state == RECV) begin rx_bitcnt[15:0] <= rx_bitcnt[15:0]+16'd1; end else begin rx_bitcnt[15:0] <= 16'd0; end end reg [15:0] tx_bitcnt; always @(posedge clk_out or posedge rst) begin if(rst) begin tx_bitcnt[15:0] <= 16'd0; end else if(tx_state == SEND) begin tx_bitcnt[15:0] <= tx_bitcnt[15:0]+16'd1; end else begin tx_bitcnt[15:0] <= 16'd0; end end reg [15:0] rest_cnt; always @(posedge clk_out or posedge rst) begin if(rst) begin rest_cnt[15:0] <= 16'd0; end else if(tx_state == REST) begin rest_cnt[15:0] <= rest_cnt[15:0]+16'd1; end else begin rest_cnt[15:0] <= 16'd0; end end // state machine reg recv_down; reg recv_down_d1; reg recv_down_d2; reg recv_down_d3; //rx always @ (*) begin case (rx_state) WAIT : begin if ( data_in_9[15:0] == FRAME_HEAD) begin //can write rx_state_next <= RECV; end else begin rx_state_next <= WAIT; end end RECV : begin // write if(rx_bitcnt[15:0] == FRAME_LENGTH - 16'b1) begin//write end rx_state_next <= WAIT; end else if(rx_bitcnt[15:0] > FRAME_MAX_LENGTH)begin //overtime rx_state_next <= WAIT; end else begin rx_state_next <= RECV; end end default : begin rx_state_next <= WAIT; end endcase end always @(posedge clk_in) begin rx_state <= rx_state_next; end //tx always @ (*) begin case (tx_state) WAIT : begin if (recv_down_d2^recv_down_d3) begin //can write tx_state_next <= SEND; end else begin tx_state_next <= WAIT; end end SEND : begin // read if(tx_bitcnt[15:0] == FRAME_LENGTH - 16'b1) begin//read end tx_state_next <= REST; end else if(tx_bitcnt[15:0] > FRAME_MAX_LENGTH)begin //overtime tx_state_next <= WAIT; end else begin tx_state_next <= SEND; end end REST : begin // rest if(rest_cnt[15:0] == REST_LENGTH - 16'b1) begin//rest end tx_state_next <= WAIT; end else if(rest_cnt[15:0] > REST_MAX_LENGTH)begin //overtime tx_state_next <= WAIT; end else begin tx_state_next <= REST; end end default : begin tx_state_next <= WAIT; end endcase end always @(posedge clk_out) begin tx_state <= tx_state_next; end //recv_down flag always @ ( posedge clk_in or posedge rst) begin if ( rst ) begin recv_down <= 1'b0; end else if((rx_state == RECV)&&(rx_state_next == WAIT)) begin recv_down <= ~recv_down; end else begin recv_down <= recv_down; end end always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin recv_down_d1 <= 1'b0; recv_down_d2 <= 1'b0; recv_down_d3 <= 1'b0; end else begin recv_down_d1 <= recv_down; recv_down_d2 <= recv_down_d1; recv_down_d3 <= recv_down_d2; end end //fifo control always @ ( posedge clk_in or posedge rst) begin if ( rst ) begin fifo_data_in <= 1'b0; end else if(rx_state == RECV) begin fifo_data_in <= data_in_9[16]; end else begin fifo_data_in <= 1'b0; end end always @ ( posedge clk_in or posedge rst) begin if ( rst ) begin fifo_wr_en <= 1'b0; end else if(rx_state == RECV ) begin fifo_wr_en <= 1'b1; end else begin fifo_wr_en <= 1'b0; end end reg data_out_reg; always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin data_out_reg <= 1'b0; end else if(valid) begin data_out_reg <= fifo_data_out; end else if(tx_state == REST) begin data_out_reg <= 1'b0; end else begin data_out_reg <= 1'b0; end end assign data_out = data_out_reg; always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin fifo_rd_en <= 1'b0; end else if(tx_state == SEND) begin fifo_rd_en <= 1'b1; end else begin fifo_rd_en <= 1'b0; end end //en create reg en_out_reg; reg en_out_reg_d1; always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin en_out_reg <= 1'b1; en_out_reg_d1 <= 1'b1; end else begin en_out_reg <= ~fifo_rd_en; en_out_reg_d1 <= en_out_reg; end end assign en_out = en_out_reg_d1; //beam_clk wire beam_clk; reg beam_clk_reg; reg beam_clk_reg_d1; reg beam_clk_reg_d2; always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin beam_clk_reg <= 1'b0; end else if(tx_state == SEND || tx_state == REST) begin beam_clk_reg <= 1'b1; end else begin beam_clk_reg <= 1'b0; end end always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin beam_clk_reg_d1 <= 1'b0; beam_clk_reg_d2 <= 1'b0; end else begin beam_clk_reg_d1 <= beam_clk_reg; beam_clk_reg_d2 <= beam_clk_reg_d1; end end assign beam_clk = beam_clk_reg_d2; //tr dary reg tr_d1; reg tr_d2; always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin tr_d1 <= 1'b0; tr_d2 <= 1'b0; end else begin tr_d1 <= tr_in; tr_d2 <= tr_d1; end end assign tr_out = tr_d2; reg dary_d1; reg dary_d2; always @ ( posedge clk_out or posedge rst) begin if ( rst ) begin dary_d1 <= 1'b0; dary_d2 <= 1'b0; end else begin dary_d1 <= dary_in; dary_d2 <= dary_d1; end end assign dary_out = dary_d2; //ant_clk reg valid_d1; always @ ( posedge clk_out or posedge rst) begin if (rst ) begin valid_d1 <= 1'b0; end else begin valid_d1 <= valid; end end always @ ( posedge clk_out or posedge rst) begin if (rst ) begin ant_clk <= 1'b1; end else if(~valid_d1 && valid) begin ant_clk <= 1'b1; end else if(beam_clk) begin ant_clk <= ~ant_clk; end else begin ant_clk <= 1'b1; end end //debug reg [31:0] freq; always @ ( posedge clk_out or posedge rst) begin if (rst ) begin freq[31:0] <= 32'b0; end else begin freq[31:0] <= {freq[30:0],data_out_reg}; end end always @ ( posedge clk_out or posedge rst) begin if (rst ) begin debug_freq[15:0] <= 16'b0; end else if(tx_bitcnt == 16'h0092) begin debug_freq[15:0] <= {freq[30],freq[28],freq[26],freq[24],freq[22],freq[20],freq[18],freq[16],freq[14],freq[12],freq[10],freq[8],freq[6],freq[4],freq[2],freq[0]}; end else begin debug_freq[15:0] <= debug_freq[15:0]; end end always @ ( posedge clk_out or posedge rst) begin if (rst ) begin debug_freq_change <= 1'b0; end else if(tx_bitcnt == 16'h0092 || tx_bitcnt == 16'h0093) begin debug_freq_change <= 1'b1; end else begin debug_freq_change <= 1'b0; end end assign debug_tr_count = 64'b0; // always @ ( posedge clk_out or posedge rst) begin // if (rst ) begin // debug_tr_count[63:0] <= 64'b0; // end // else if(tr_d1 != tr_d2) begin // debug_tr_count[63:0] <= 64'b0; // end // else begin // debug_tr_count[63:0] <= debug_tr_count[63:0] + 64'b1; // end // end endmodule