/********************************************** _ _ Cook Darwin __

_ descript: author : Cook.Darwin Version: VERA.0.0 creaded: 2016/10/12 madified: ***********************************************/ `timescale 1ns / 1ps module axi4_to_native_for_ddr_ip #(

parameter ADDR_WIDTH            = 27,
parameter DATA_WIDTH            = 256

)(

axi_inf.slaver                  axi_inf,
output logic[ADDR_WIDTH-1:0]    app_addr,
output logic[2:0]               app_cmd,
output logic                    app_en,
output logic[DATA_WIDTH-1:0]    app_wdf_data,
output logic                    app_wdf_end,
output logic[DATA_WIDTH/8-1:0]  app_wdf_mask,
output logic                    app_wdf_wren,
input  [DATA_WIDTH-1:0]         app_rd_data,
input                           app_rd_data_end,
input                           app_rd_data_valid,
input                           app_rdy,
input                           app_wdf_rdy,
input                           init_calib_complete

);

logic clock,rst;

assign clock = axi_inf.axi_aclk; assign rst = !axi_inf.axi_aresetn; //assign rst = !axi_inf.axi_aresetn || axi_inf.axi_wevld || axi_inf.axi_revld; typedef enum {

NOP=0,
WIDLE=1,
RIDLE=2,
EXEC_WR=3,
WR_CMD_E=4,
WR_FIFO_E=5,
WR_END=6,
EXEC_RD=7,
RD_FIFO_E=8,
RD_END=9,
RD_AXI_E=10,
APP_CMD_E=11,
CLEAR_WR_FIFO=12
} MASTER_STATE;

MASTER_STATE mnstate,mcstate;

always@(posedge clock,posedge rst)begin

if(rst)     mcstate <= NOP;
// else if(axi_inf.axi_wevld ||��?axi_inf.axi_revld)
//             mcstate <= NOP;
else        mcstate <= mnstate;

end

logic wr_fifo_empty; // (* dont_touch = “true” *) // logic app_en_last; (* dont_touch = “true” *) logic app_en_wr_last; (* dont_touch = “true” *) logic app_en_rd_last; logic [8:0] app_len; logic [8:0] app_wr_len; logic [8:0] app_rd_len; logic [9:0] wdf_cnt; (* dont_touch = “true” *) logic wdf_last;

always@(*)

case(mcstate)
NOP:
    if(init_calib_complete && app_rdy)
            mnstate = WIDLE;
    else    mnstate = NOP;
WIDLE:
    if(axi_inf.axi_awvalid && axi_inf.axi_awready)
            mnstate = EXEC_WR;
    else    mnstate = RIDLE;
RIDLE:
    if(axi_inf.axi_arvalid && axi_inf.axi_arready)
            mnstate = EXEC_RD;
    else    mnstate = WIDLE;
EXEC_WR:
    // if(axi_inf.axi_wlast && axi_inf.axi_wvalid && axi_inf.axi_wready)
    // if(!wr_fifo_empty && axi_inf.axi_wvalid && axi_inf.axi_wready)
    if(!wr_fifo_empty)
            // mnstate = WR_FIFO_E;
            mnstate = WR_CMD_E;
    else    mnstate = EXEC_WR;
WR_CMD_E:
    if(app_en_wr_last && app_rdy && app_en && wdf_last && app_wdf_wren && app_wdf_rdy)
            mnstate = WR_END;
    else if(app_en_wr_last && app_rdy && app_en)
    // if(app_en_last)
            mnstate = WR_FIFO_E;
    else if(wdf_last && app_wdf_wren && app_wdf_rdy)           //data burst first
            mnstate = APP_CMD_E;
    else    mnstate = WR_CMD_E;
APP_CMD_E:
    if(app_en_wr_last && app_rdy && app_en)
            mnstate = WR_END;
    else    mnstate = APP_CMD_E;
WR_FIFO_E:
    // if(wr_fifo_empty)
    if(wdf_last && app_wdf_wren && app_wdf_rdy)
    // if(app_en_last && wr_fifo_empty)
            mnstate = WR_END;
    else    mnstate = WR_FIFO_E;
WR_END:
    if(axi_inf.axi_bready)begin
        if(wr_fifo_empty)
                mnstate = RIDLE;
        else    mnstate = CLEAR_WR_FIFO;
    end else    mnstate = WR_END;
EXEC_RD:
    if(app_en_rd_last && app_rdy && app_en)
            mnstate = RD_AXI_E;
    else    mnstate = EXEC_RD;
RD_AXI_E:
    if(axi_inf.axi_rvalid && axi_inf.axi_rlast && axi_inf.axi_rready)
            mnstate = WIDLE;
    else    mnstate = RD_AXI_E;
// EXEC_RD:
//     // if(axi_inf.axi_rvalid && axi_inf.axi_rlast && axi_inf.axi_rready)
//     if(app_en_last && app_rdy)
//             mnstate = RD_FIFO_E;
//     else    mnstate = EXEC_RD;
// RD_FIFO_E:
//     if(axi_inf.axi_rvalid && axi_inf.axi_rlast && axi_inf.axi_rready)
//             mnstate = IDLE;
//     else    mnstate = RD_FIFO_E;
CLEAR_WR_FIFO:
    if(wr_fifo_empty)
            mnstate = RIDLE;
    else    mnstate = CLEAR_WR_FIFO;
default:    mnstate = NOP;
endcase

//—>> FORCE CLEAR FIFO <<—————— logic clear_wr_fifo_en; always@(posedge clock,posedge rst)

if(rst) clear_wr_fifo_en    <= 1'b0;
else begin
    case(mnstate)
    CLEAR_WR_FIFO:
        clear_wr_fifo_en    <= 1'b1;
    default:
        clear_wr_fifo_en    <= 1'b0;
    endcase
end

//—<< FORCE CLEAR FIFO >>—————— logic wr_enable,rd_enable; logic rd_app_enable;

always@(posedge clock,posedge rst)

if(rst) wr_enable   <= 1'b0;
else
    case(mnstate)
    // EXEC_WR,WR_CMD_E,WR_FIFO_E:
    WR_CMD_E,APP_CMD_E:
                wr_enable   <= 1'b1;
    default:    wr_enable   <= 1'b0;
    endcase

always@(posedge clock,posedge rst)

if(rst) rd_app_enable   <= 1'b0;
else
    case(mnstate)
    EXEC_RD,RD_AXI_E:
                rd_app_enable   <= 1'b1;
    default:    rd_app_enable   <= 1'b0;
    endcase

always@(posedge clock,posedge rst)

if(rst) rd_enable   <= 1'b0;
else
    case(mnstate)
    EXEC_RD:
                rd_enable   <= 1'b1;
    default:    rd_enable   <= 1'b0;
    endcase

//—>> WR DDR DATA <<——————- logic rd_fifo_full; logic rd_fifo_empty; (* dont_touch = “true” *) logic rd_fifo_en; // assign rd_fifo_en = (rd_enable && axi_inf.axi_rready) || wr_enable; assign rd_fifo_en = (rd_app_enable && axi_inf.axi_rready && !rd_fifo_empty) ; // assign rd_fifo_en = (rd_app_enable && axi_inf.axi_rready && !rd_fifo_empty) || wr_enable; generate if(DATA_WIDTH!=512)begin FIFO_DDR_IP_BRG FIFO_DDR_IP_BRG_rd ( /* input */ .clk (clock ), /* input */ .rst (rst ), /* input [255:0] */ .din (app_rd_data ), // /* input */ .wr_en (app_rd_data_valid && !rd_fifo_full ), /* input */ .wr_en (app_rd_data_valid ), /* input */ .rd_en (/*rd_enable && axi_inf.axi_rready*/rd_fifo_en ), /* output [255:0] */ .dout (axi_inf.axi_rdata ), /* output */ .full (rd_fifo_full ), /* output */ .empty (rd_fifo_empty ) ); end else begin FIFO_DDR_IP_BRG_512 FIFO_DDR_IP_BRG_rd ( /* input */ .clk (clock ), /* input */ .srst (rst ), /* input [511:0] */ .din (app_rd_data ), // /* input */ .wr_en (app_rd_data_valid && !rd_fifo_full ), /* input */ .wr_en (app_rd_data_valid ), /* input */ .rd_en (/*rd_enable && axi_inf.axi_rready */rd_fifo_en ), /* output [511:0] */ .dout (axi_inf.axi_rdata ), /* output */ .full (rd_fifo_full ), /* output */ .empty (rd_fifo_empty ) ); end endgenerate

assign axi_inf.axi_rvalid = !rd_fifo_empty && rd_app_enable; //—<< WR DDR DATA >>——————- //—>> RD DDR DATA <<——————- (* dont_touch = “true” *) wire wr_fifo_wen; // assign wr_fifo_wen = wr_enable && axi_inf.axi_wvalid && axi_inf.axi_wready; assign wr_fifo_wen = axi_inf.axi_wvalid && axi_inf.axi_wready; (* dont_touch = “true” *) wire wr_fifo_ren; // assign wr_fifo_ren = (wr_enable && app_wdf_rdy) || rd_enable; assign wr_fifo_ren = (app_wdf_wren && app_wdf_rdy) || clear_wr_fifo_en; // assign wr_fifo_ren = (app_wdf_wren && app_wdf_rdy); logic wr_fifo_full; generate if(DATA_WIDTH!=512)begin FIFO_DDR_IP_BRG FIFO_DDR_IP_BRG_wr ( /* input */ .clk (clock ), /* input */ .rst (rst ), /* input [255:0] */ .din (axi_inf.axi_wdata ), /* input */ .wr_en (/*wr_enable && axi_inf.axi_wvalid && axi_inf.axi_wready*/wr_fifo_wen ), /* input */ .rd_en (/*wr_enable && app_wdf_rdy*/ wr_fifo_ren ), /* output [255:0] */ .dout (app_wdf_data ), /* output */ .full (wr_fifo_full ), /* output */ .empty (wr_fifo_empty ) ); end else begin FIFO_DDR_IP_BRG_512 FIFO_DDR_IP_BRG_wr ( /* input */ .clk (clock ), /* input */ .srst (rst ), /* input [511:0] */ .din (axi_inf.axi_wdata ), /* input */ .wr_en (/*wr_enable && axi_inf.axi_wvalid && axi_inf.axi_wready*/ wr_fifo_wen ), /* input */ .rd_en (/*wr_enable && app_wdf_rdy*/ wr_fifo_ren ), /* output [511:0] */ .dout (app_wdf_data ), /* output */ .full (wr_fifo_full ), /* output */ .empty (wr_fifo_empty ) ); end endgenerate

// assign axi_inf.axi_wready = !wr_fifo_full && wr_enable; // assign axi_inf.axi_wready = wr_enable; assign axi_inf.axi_wready = !wr_fifo_full; // assign app_wdf_wren = !wr_fifo_empty; assign app_wdf_mask = {(DATA_WIDTH/8){1'b0}}; assign app_wdf_end = 1'b1;

//—->> APP WRITE <<——————– always@(posedge clock,posedge rst)

if(rst) wdf_cnt <= '0;
else begin
    if(axi_inf.axi_awready)
            wdf_cnt <= '0;
    else if(wdf_last && app_wdf_wren && app_wdf_rdy)
            wdf_cnt <= '0;
    else if(app_wdf_wren && app_wdf_rdy)
            wdf_cnt <= wdf_cnt + 1'b1;
    else    wdf_cnt <= wdf_cnt;
end

always@(posedge clock,posedge rst)

if(rst) wdf_last    <= 1'b0;
else begin
    if(axi_inf.axi_awvalid && axi_inf.axi_awready && axi_inf.axi_awlen==0)
            wdf_last    <= 1'b1;
    else if(wdf_last && app_wdf_wren && app_wdf_rdy)
            wdf_last    <= 1'b0;
    else if(app_wdf_wren && app_wdf_rdy && (wdf_cnt == app_wr_len-2))
            wdf_last    <= 1'b1;
    else    wdf_last    <= wdf_last;
end

always@(posedge clock,posedge rst)

if(rst) app_wdf_wren   <= 1'b0;
else
    case(mnstate)
    WR_CMD_E,WR_FIFO_E:
                app_wdf_wren   <= 1'b1;
    default:    app_wdf_wren   <= 1'b0;
    endcase

//—-<< APP WRITE >>——————– //—>> RD DDR DATA <<——————- //—>> WR AXI CMD <<——————– // typedef enum {AWIDLE,AWRDY,AWEND} AWSTATE; // AWSTATE awcstate,awnstate; // // always@(posedge clock,posedge rst) // if(rst) awcstate <= AWIDLE; // else awcstate <= awnstate; // // always@(*) // case(awcstate) // AWIDLE: // if(wr_enable) // awnstate = AWRDY; // else awnstate = AWIDLE; // AWRDY: // if(axi_inf.axi_awvalid) // awnstate = AWEND; // else awnstate = AWIDLE; // AWEND: // if(!wr_enable) // awnstate = AWIDLE; // else awnstate = AWEND; // default: awnstate = AWIDLE; // endcase

always@(posedge clock,posedge rst)

if(rst)     axi_inf.axi_awready <= 1'b0;
else
    case(mnstate)
    WIDLE:  axi_inf.axi_awready <= 1'b1;
    default:axi_inf.axi_awready <= 1'b0;
    endcase

always@(posedge clock,posedge rst)

if(rst)     axi_inf.axi_arready <= 1'b0;
else
    case(mnstate)
    RIDLE:  axi_inf.axi_arready <= 1'b1;
    default:axi_inf.axi_arready <= 1'b0;
    endcase

//—<< WR AXI CMD >>——————– //—>> AXI BURST <<—————— // always@(posedge clock,posedge rst) // if(rst) app_len <= 9'd0; // else begin // if(axi_inf.axi_awvalid && axi_inf.axi_awready) // app_len <= axi_inf.axi_awlen+1'b1; // else if(axi_inf.axi_arvalid && axi_inf.axi_arready) // app_len <= axi_inf.axi_arlen+1'b1; // else app_len <= app_len; // end

always@(posedge clock,posedge rst)

if(rst) app_wr_len    <= 9'd0;
else begin
    if(axi_inf.axi_awvalid && axi_inf.axi_awready)
            app_wr_len    <= axi_inf.axi_awlen+1'b1;
    else    app_wr_len    <= app_wr_len;
end

always@(posedge clock,posedge rst)

if(rst) app_rd_len    <= 9'd0;
else begin
    if(axi_inf.axi_arvalid && axi_inf.axi_arready)
            app_rd_len    <= axi_inf.axi_arlen+1'b1;
    else    app_rd_len    <= app_rd_len;
end

logic [8:0] len_cnt; always@(posedge clock,posedge rst)

if(rst) len_cnt  <=  9'd0;
else begin
    if(wr_enable || rd_enable)begin
        if(app_rdy && app_en)
                len_cnt  <= len_cnt + 1'b1;
        else    len_cnt  <= len_cnt;
    end else    len_cnt  <= 9'd0;
end

//—<< AXI BURST >>—————— // (* dont_touch = “true” *) // logic app_en_last; // always@(posedge clock,posedge rst) // if(rst) app_en_last <= 1'b0; // else begin // // if(wr_enable || rd_enable) // // // app_en_last <= (len_cnt==(app_len-1 ) && app_en && app_rdy) || app_en_last; // // app_en_last <= len_cnt==(app_len-1 ) || (len_cnt==(app_len-2 ) && app_en && app_rdy); // // // else if(app_en_last && app_rdy && app_en) // // // app_en_last <= 1'b0; // // // else app_en_last <= app_en_last; // // else app_en_last <= 1'b0; // if(wr_enable) // app_en_last <= len_cnt==(app_wr_len-1 ) || (len_cnt==(app_wr_len-2 ) && app_en && app_rdy); // else if(rd_enable) // app_en_last <= len_cnt==(app_rd_len-1 ) || (len_cnt==(app_rd_len-2 ) && app_en && app_rdy); // else app_en_last <= 1'b0; // end

// always@(posedge clock,posedge rst)

if(rst) app_en_wr_last   <= 1'b0;
else begin
    if(axi_inf.axi_awvalid && axi_inf.axi_awready && axi_inf.axi_awlen==0)
            app_en_wr_last   <= 1'b1;
    else if(app_en && app_rdy && app_en_wr_last)
            app_en_wr_last   <= 1'b0;
    else if(len_cnt==(app_wr_len-2 ) && app_en && app_rdy)
            app_en_wr_last   <= 1'b1;
    else    app_en_wr_last   <= app_en_wr_last;
end

always@(posedge clock,posedge rst)

if(rst) app_en_rd_last   <= 1'b0;
else begin
    if(axi_inf.axi_arvalid && axi_inf.axi_arready && axi_inf.axi_arlen==0)
            app_en_rd_last  <= 1'b1;
    else if(rd_enable)
            app_en_rd_last   <= len_cnt==(app_rd_len-1 ) || (len_cnt==(app_rd_len-2 ) && app_en && app_rdy);
    else    app_en_rd_last   <= 1'b0;
end

always@(posedge clock,posedge rst)

if(rst) axi_inf.axi_bvalid   <= 1'b0;
else
    case(mnstate)
    WR_END:     axi_inf.axi_bvalid   <= 1'b1;
    default:    axi_inf.axi_bvalid   <= 1'b0;
    endcase

assign axi_inf.axi_bresp = 2'b00; // assign axi_inf.axi_bid = 0; // assign app_en_last = app_en_last; //—<< AXI WR BURST >>—————— //—>> DDR ADDR <<——————- logic [26:0] base_wr_addr;

always@(posedge clock,posedge rst)

if(rst) base_wr_addr    <= 27'd0;
else begin
    if(axi_inf.axi_awvalid && axi_inf.axi_awready)
            base_wr_addr    <= axi_inf.axi_awaddr;
    else    base_wr_addr    <= base_wr_addr;
end

always@(posedge clock,posedge rst)begin

if(rst)     app_addr    <= 27'd0;
else begin
    if(app_rdy && app_en)
            app_addr    <= app_addr + 8;
    else if(axi_inf.axi_awvalid && axi_inf.axi_awready)
            app_addr    <= axi_inf.axi_awaddr;
    else if(axi_inf.axi_arvalid && axi_inf.axi_arready)
            app_addr    <= axi_inf.axi_araddr;
    else    app_addr    <= app_addr;
end

end

// always@(posedge clock,posedge rst) // if(rst) app_en <= 1'b0; // else begin // // // if(wr_enable || rd_enable)begin // // // app_en <= 1'b1; // // if(wr_enable || rd_enable)begin // // if(app_en_last)begin // // // app_en <= 1'b0; // // // app_en <= !app_rdy; // // if(app_en)begin // // if(app_rdy) // // app_en <= 1'b0; // // else app_en <= app_en; // // end else app_en <= 1'b0; // // end else app_en <= 1'b1; // // // // // if(app_en_last && app_en && app_rdy) // // // app_en <= 1'b0; // // // else app_en <= app_en; // // // // end else app_en <= 1'b0; // // // end

assign app_en = wr_enable || rd_enable; assign app_cmd = wr_enable ? 3'b000 : (rd_enable? 3'b001 : 3'b111); // reg [2:0] app_cmd_reg; // always@(posedge clock,posedge rst) // if(rst) app_cmd_reg <= 3'b111; // else begin // if(wr_enable) // app_cmd_reg <= 3'b000; // else if(rd_enable) // app_cmd_reg <= 3'b001; // else app_cmd_reg <= app_cmd_reg; // end // // assign app_cmd = app_cmd_reg;

//—>> axi read data last <<————- logic [8:0] axi_rd_cnt;

always@(posedge clock,posedge rst)

if(rst)     axi_rd_cnt  <= 9'd0;
else begin
    // if(rd_enable)begin
    if(rd_app_enable)begin
        if(axi_inf.axi_rready && axi_inf.axi_rvalid)
                axi_rd_cnt  <= axi_rd_cnt + 1'b1;
        else    axi_rd_cnt  <= axi_rd_cnt;
    end else    axi_rd_cnt  <= 9'd0;
end

always@(posedge clock,posedge rst)

if(rst) axi_inf.axi_rlast  <= 1'b0;
else begin
    // if(!rd_enable)
    if(!rd_app_enable)
            axi_inf.axi_rlast   <= 1'b0;
    else if(app_rd_len==1)
            axi_inf.axi_rlast   <= 1'b1;
    else if(axi_inf.axi_rready && axi_inf.axi_rvalid && axi_inf.axi_rlast)
            axi_inf.axi_rlast   <= 1'b0;
    else if(axi_inf.axi_rready && axi_inf.axi_rvalid && axi_rd_cnt == (app_rd_len-2))
            axi_inf.axi_rlast   <= 1'b1;
    else    axi_inf.axi_rlast   <= axi_inf.axi_rlast;
end

//—<< axi read data last >>————- // assign axi_inf.axi_rid = 0; assign axi_inf.axi_rresp = 2'b00; //—>> WR ID <<————————– always@(posedge clock,posedge rst)

if(rst)     axi_inf.axi_bid <= 0;
else begin
    if(axi_inf.axi_awvalid && axi_inf.axi_awready)
            axi_inf.axi_bid <= axi_inf.axi_awid;
    else    axi_inf.axi_bid <= axi_inf.axi_bid;
end

//—<< WR ID >>————————– //—>> RD ID <<————————– always@(posedge clock,posedge rst)

if(rst)     axi_inf.axi_rid <= 0;
else begin
    if(axi_inf.axi_arvalid && axi_inf.axi_arready)
            axi_inf.axi_rid <= axi_inf.axi_arid;
    else    axi_inf.axi_rid <= axi_inf.axi_rid;
end

//—<< RD ID >>————————– //—>> APP WRITE CNT <<—————— (* dont_touch=“true” *) logic [5:0] app_wr_cmd_cnt; (* dont_touch=“true” *) logic [5:0] app_wr_data_cnt; (* dont_touch=“true” *) logic [5:0] app_cnt_delta;

always@(posedge clock,posedge rst)

if(rst)     app_wr_cmd_cnt  <= '0;
else begin
    if(app_en && app_rdy && app_cmd == 2'b00)
            app_wr_cmd_cnt  <= app_wr_cmd_cnt + 1'b1;
    else    app_wr_cmd_cnt  <= app_wr_cmd_cnt;
end

always@(posedge clock,posedge rst)

if(rst)     app_wr_data_cnt  <= '0;
else begin
    if(app_wdf_wren && app_wdf_rdy)
    // if(app_rd_data_valid)
            app_wr_data_cnt  <= app_wr_data_cnt + 1'b1;
    else    app_wr_data_cnt  <= app_wr_data_cnt;
end

always@(posedge clock,posedge rst)

if(rst)     app_cnt_delta   <= '0;
else begin
    if(!app_wdf_wren && !app_en)
    // if(!app_rd_data_valid && !app_en)
            app_cnt_delta   <= app_wr_cmd_cnt-app_wr_data_cnt;
    else    app_cnt_delta   <= app_cnt_delta;
end

//—<< APP WRITE CNT >>——————

endmodule