`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2023/02/22 21:36:32 // Design Name: // Module Name: c2c_bridge_dma // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// /////FRAME HEAD(32bit)/////FRAME LENGTH(32bit)/////DATA/////////////////////////// ////////////////////////////////////////////////////////////////////////////////// module c2c_bridge_dma #( parameter [31:0] FRAME_HEAD = 31'h7E7E7E7E, parameter [31:0] FRAME_MAX_LENGTH = 31'h00000400 ) ( input clk , // input clk, 96Mhz input rst , // input rst, active high //interface data input c2c_clkin , output c2c_clkout , input c2c_din , output c2c_dout , //dma fifo interface input [31:0] c2c_tx_fifo_tdata , input c2c_tx_fifo_tlast , output reg c2c_tx_fifo_tready , input c2c_tx_fifo_tvalid , output reg [31:0] c2c_rx_fifo_tdata , output reg c2c_rx_fifo_tlast , input c2c_rx_fifo_tready , output reg c2c_rx_fifo_tvalid ); ////////////////////////////////////////////////////////////////////////////////// /////TX ignore tlast, each 32 clk make ready on and get a 32bit data ////////////////////////////////////////////////////////////////////////////////// reg [4:0] tx_cnt_32; always @(posedge clk) begin if(rst) begin tx_cnt_32[4:0] <= 5'd0; end else begin tx_cnt_32[4:0] <= tx_cnt_32[4:0] + 5'd1; end end always @(posedge clk) begin if(tx_cnt_32[4:0] == 5'd1) begin c2c_tx_fifo_tready <= 1'b1; end else begin c2c_tx_fifo_tready <= 1'b0; end end reg [31:0] tx_data_32 = 32'b0; always @(posedge clk) begin if(c2c_tx_fifo_tready == 1'b1) begin if(c2c_tx_fifo_tvalid == 1'b1) begin tx_data_32 <= c2c_tx_fifo_tdata; end else begin tx_data_32 <= 32'b0; end end else begin tx_data_32 <= {tx_data_32[30:0],1'b0}; end end assign c2c_clkout = clk; assign c2c_dout = tx_data_32[31]; ////////////////////////////////////////////////////////////////////////////////// /////RX ignore tready, each 32 clk make valid on and send a 32bit data, final creat tlast ////////////////////////////////////////////////////////////////////////////////// reg [31:0] rx_data_32 = 32'b0; always @(posedge c2c_clkin) begin rx_data_32 <= {rx_data_32[30:0],c2c_din}; end // state machine reg [3:0] rx_state_next; reg [3:0] rx_state; localparam RX_WAIT = 4'd0; localparam RX_PLWRITE = 4'd1; always @ (*) begin case (rx_state) RX_WAIT : begin //wait for frame head if (rx_data_32 == FRAME_HEAD) begin rx_state_next <= RX_PLWRITE; end else begin rx_state_next <= RX_WAIT; end end RX_PLWRITE : begin // if(rx_data_cnt[36:5] == rx_frame_length[31:0] - 32'b1) begin rx_state_next <= RX_WAIT; end else if(rx_data_cnt[36:5] > FRAME_MAX_LENGTH)begin //overtime rx_state_next <= RX_WAIT; end else begin rx_state_next <= RX_PLWRITE; end end default : begin rx_state_next <= RX_WAIT; end endcase end always @(posedge c2c_clkin) begin rx_state <= rx_state_next; end // reg [36:0] rx_data_cnt = 37'd0; always @(posedge c2c_clkin) begin if(rx_state == RX_WAIT) begin rx_data_cnt[36:0] <= 37'd0; end else begin rx_data_cnt[36:0] <= rx_data_cnt[36:0] + 37'd1; end end reg [31:0] rx_frame_length = FRAME_MAX_LENGTH; always @(posedge c2c_clkin) begin if(rx_state == RX_WAIT)begin rx_frame_length[31:0] <= FRAME_MAX_LENGTH; end else if(rx_data_cnt == 37'd31) begin rx_frame_length[31:0] <= (rx_data_32[1:0] > 0) ? ({2'b0,rx_data_32[31:2]} + 32'b1) : ({2'b0,rx_data_32[31:2]}); end else begin rx_frame_length[31:0] <= rx_frame_length[31:0]; end end reg [31:0] rx_data_32_d1; reg [31:0] rx_data_32_d2; always @(posedge c2c_clkin) begin rx_data_32_d1 <= rx_data_32; rx_data_32_d2 <= rx_data_32_d1; end always @(posedge c2c_clkin) begin c2c_rx_fifo_tdata <= rx_data_32_d2; end //fifo ctrl always @(posedge c2c_clkin) begin if(rx_data_cnt[4:0] == 5'd1) begin c2c_rx_fifo_tvalid <= 1'b1; end else begin c2c_rx_fifo_tvalid <= 1'b0; end end reg c2c_rx_fifo_tlast_d0; always @(posedge c2c_clkin) begin if(rx_state == RX_PLWRITE && rx_state_next == RX_WAIT) begin c2c_rx_fifo_tlast_d0 <= 1'b1; end else begin c2c_rx_fifo_tlast_d0 <= 1'b0; end end always @(posedge c2c_clkin) begin c2c_rx_fifo_tlast <= c2c_rx_fifo_tlast_d0; end endmodule