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

_ descript:

out of order

author : Cook.Darwin Version: VERA.0.0 creaded: 2017/3/7 madified: ***********************************************/ `timescale 1ns/1ps module axi4_partition_rd_OD #(

parameter PSIZE = 128 //master side
// parameter real ADDR_STEP = 1

)(

axi_inf.slaver_rd slaver,
axi_inf.master_rd master

);

// localparam ADDR_STEP = PSIZE*master.DSIZE / slaver.DSIZE;

import SystemPkg::*;

initial begin

assert(slaver.IDSIZE+4 == master.IDSIZE)
else begin
    $error("SLAVER AXIS IDSIZE+4 != MASTER AXIS IDSIZE");
    $stop;
end
assert(master.IDSIZE > 4)
else begin
    $error("MASTER AXI IDSIZE[%d] MUST LARGER THAN 4",master.IDSIZE);
    $stop;
end

end

logic clock,rst_n;

assign clock = slaver.axi_aclk; assign rst_n = slaver.axi_aresetn;

//—>> PARTITION STATE MACHINE <<———————- logic p_arvalid,p_arready; logic [slaver.IDSIZE+3:0] p_id; logic [master.ASIZE-1:0] p_araddr; logic [master.LSIZE-1:0] p_arlen; logic p_ar_last;

typedef enum {IDLE,GET_IP_A,P_A,P_R,O_A,O_R,UP_LAST,L_A,L_R} STATUS;

STATUS nstate,cstate;

always@(posedge clock,negedge rst_n)begin

if(~rst_n)  cstate  <= IDLE;
else        cstate  <= nstate;

end

logic len_overflow; logic partition_completel;

always_comb begin

case(cstate)
IDLE:
    if(slaver.axi_arvalid && slaver.axi_arready)
            nstate  = GET_IP_A;
    else    nstate  = IDLE;
GET_IP_A:
    if(len_overflow)
            nstate  = P_A;
    else    nstate  = O_A;
P_A:
    if(p_arvalid && p_arready)
            nstate  = P_R;
    else    nstate  = P_A;
P_R:
    if(partition_completel)
            // nstate  = L_A;
            nstate  = UP_LAST;
    else    nstate  = P_A;
L_A:
    if(p_arvalid && p_arready)
            nstate  = L_R;
    else    nstate  = L_A;
L_R:        nstate  = UP_LAST;
O_A:
    if(p_arvalid && p_arready)
            nstate  = O_R;
    else    nstate  = O_A;
O_R:        nstate  = UP_LAST;
UP_LAST:    nstate  = IDLE;
default:    nstate  = IDLE;
endcase

end

always@(posedge clock,negedge rst_n)

if(~rst_n)  p_id    <= '0;
else
    if(p_arvalid && p_arready)
            p_id    <= p_id + 1'b1;
    else    p_id    <= p_id;

//—>>> AUXILIARY FIFO <<<———————— logic [slaver.IDSIZE+3:0] rp_id; logic [master.ASIZE-1:0] rp_araddr; logic [master.LSIZE-1:0] rp_arlen; logic rp_ar_last; logic fifo_empty; logic fifo_full; logic id_fifo_empty; logic id_fifo_full;

common_fifo #(

.DEPTH  (4      ),
.DSIZE  (1+4+master.ASIZE+master.LSIZE+slaver.IDSIZE      )

)common_fifo_inst( /* input */ .clock (clock ), /* input */ .rst_n (rst_n ), /* input [DSIZE-1:0] */ .wdata ({p_ar_last,p_id,p_araddr,p_arlen} ), /* input */ .wr_en (p_arvalid && p_arready ), /* output logic */ .rdata ({rp_ar_last,rp_id,rp_araddr,rp_arlen} ), /* input */ .rd_en (master.axi_arready && !fifo_empty && !id_fifo_full ), // STOP,untill rlast /* output logic */ .count ( ), /* output logic */ .empty (fifo_empty ), /* output logic */ .full (fifo_full ) );

assign master.axi_arvalid = !fifo_empty && !id_fifo_full; // STOP,untill rlast

assign master.axi_arid = rp_id; assign master.axi_araddr = rp_araddr; assign master.axi_arlen = rp_arlen;

// (* dont_touch = “true” *) logic len_cnt; always@(posedge clock,negedge rst_n)

if(~rst_n)  len_cnt <= '0;
else begin
    if(p_arvalid && p_arready && p_ar_last)
            len_cnt <= '0;
    else if(p_arvalid && p_arready)
            len_cnt <= len_cnt + 1'b1;
    else    len_cnt <= len_cnt;
end

//—<<< AUXILIARY FIFO >>>———————— //—>>> STREAM ID FIFO <<<———————— logic [slaver.IDSIZE+3:0] stream_id; logic [master.ASIZE-1:0] stream_araddr; logic [master.LSIZE-1:0] stream_arlen; logic stream_last;

common_fifo #(

.DEPTH  (4      ),
.DSIZE  (1+4+master.ASIZE+master.LSIZE+slaver.IDSIZE      )

)id_fifo_inst( /* input */ .clock (clock ), /* input */ .rst_n (rst_n ), /* input [DSIZE-1:0] */ .wdata ({rp_ar_last,rp_id,rp_araddr,rp_arlen} ), /* input */ .wr_en ((master.axi_arvalid && master.axi_arready) ), /* output logic */ .rdata ({stream_last,stream_id,stream_araddr,stream_arlen} ), /* input */ .rd_en ((master.axi_rvalid && master.axi_rready && master.axi_rlast)), /* output logic */ .count ( ), /* output logic */ .empty (id_fifo_empty ), /* output logic */ .full (id_fifo_full ) );

// assign slaver.axi_arready = !fifo_full && !id_fifo_full; assign p_arready = !fifo_full && !id_fifo_full; //—<<< STREAM ID FIFO >>>———————— //—<< PARTITION STATE MACHINE >>———————- //—>> UP STREAM <<————————— always@(posedge clock,negedge rst_n)

if(~rst_n)  slaver.axi_arready  <= 1'b0;
else
    case(nstate)
    IDLE:   slaver.axi_arready  <= 1'b1;
    default:slaver.axi_arready  <= 1'b0;
    endcase

//—<< UP STREAM >>————————— //—->> DOWN STREAM <<———————— always@(posedge clock,negedge rst_n)

if(~rst_n)  p_arvalid <= 1'b0;
else
    case(nstate)
    P_A,O_A,L_A:
            p_arvalid <= 1'b1;
    default:p_arvalid <= 1'b0;
    endcase

//—-<< DOWN STREAM >>———————— //—->> LAST AR <<—————————- logic [31:0] length;

always@(posedge clock,negedge rst_n)

if(~rst_n)  p_ar_last    <= 1'b0;
else
    case(nstate)
    // O_A,L_A:
    O_A:
            p_ar_last   <= 1'b1;
    P_A:    p_ar_last   <= (length <= PSIZE);
    default:p_ar_last   <= 1'b0;
    endcase

//—-<< LAST AR >>—————————- //—->> LENDTH CTRL <<————————

always@(posedge clock,negedge rst_n)

if(~rst_n)  len_overflow    <= 1'b0;
else begin
    if(slaver.axi_arvalid  && slaver.axi_arready )
            len_overflow    <= slaver.axi_arlen + 1 > PSIZE;
    else if(slaver.axi_rready && slaver.axi_rvalid && slaver.axi_rlast)
            len_overflow    <= 1'b0;
    else    len_overflow    <= len_overflow;
end

always@(posedge clock,negedge rst_n)

if(~rst_n)  length    <= '0;
else begin
    if(slaver.axi_arvalid  && slaver.axi_arready )
            length    <= slaver.axi_arlen + 1 ;
    else if(p_arvalid  && p_arready)begin
        if(length >= PSIZE)
                length    <= length - PSIZE;
        else    length    <= '0;
    end else    length    <= length;
end

always@(posedge clock,negedge rst_n)

if(~rst_n)  p_arlen   <= '0;
else begin
    if(length>=PSIZE)
            p_arlen   <= PSIZE-1;
    else    p_arlen   <= length-1;
end

always@(posedge clock,negedge rst_n)

if(~rst_n)  partition_completel <= 1'b0;
else begin
    partition_completel <= (length <= PSIZE);
end

//—-<< LENDTH CTRL >>———————— //—->> ADDR CTRL <<———————— // (* dont_touch = “true” *) // logic addr_step_int; // assign addr_step_int = $rtoi(slaver.ADDR_STEP*1024);

always@(posedge clock,negedge rst_n)

if(~rst_n)  p_araddr   <= '0;
else begin
    if(slaver.axi_arvalid  && slaver.axi_arready)
            p_araddr   <= slaver.axi_araddr;
    else if(p_arvalid  && p_arready)
            p_araddr   <= p_araddr + (PSIZE*slaver.ADDR_STEP)/1024;
            // p_araddr   <= p_araddr + (PSIZE*addr_step_int)/1024;
    else    p_araddr   <= p_araddr;
end

//—-<< ADDR CTRL >>———————— //—->> DATA STREAM <<———————— axi_stream_inf #(

.DSIZE(master.DSIZE+slaver.IDSIZE)

)axis_in(

.aclk        (master.axi_aclk    ),
.aresetn     (master.axi_aresetn  ),
.aclken      (1'b1               )

);

axi_stream_inf #(

.DSIZE(slaver.DSIZE+slaver.IDSIZE)

)axis_out(

.aclk        (slaver.axi_aclk   ),
.aresetn     (slaver.axi_aresetn ),
.aclken      (1'b1               )

);

// axi_stream_partition axi_stream_partition_inst( // /* input */ .valve (valve ), // /* input [31:0] */ .partition_len (PSIZE-1 ), //[0] mean 1 len // /* output */ .req_new_len ( ), //it is usefull, when last stream length is only one // /* axi_stream_inf.slaver */ .axis_in (axis_in ), // /* axi_stream_inf.master */ .axis_out (axis_out ) // );

axis_connect_pipe axis_connect_pipe_inst( /* axi_stream_inf.slaver */ .axis_in (axis_in ), /* axi_stream_inf.master */ .axis_out (axis_out ) );

assign axis_in.axis_tvalid = master.axi_rvalid; assign axis_in.axis_tdata = {master.axi_rid[master.IDSIZE-1 + (master.IDSIZE<5)*10:4],master.axi_rdata}; assign axis_in.axis_tlast = master.axi_rlast && stream_last; assign axis_in.axis_tkeep = '1; assign axis_in.axis_tuser = '0; assign master.axi_rready = axis_in.axis_tready;

assign slaver.axi_rvalid = axis_out.axis_tvalid; assign {slaver.axi_rid,slaver.axi_rdata} = axis_out.axis_tdata; assign slaver.axi_rlast = axis_out.axis_tlast; assign axis_out.axis_tready= slaver.axi_rready; //—-<< DATA STREAM >>———————— //—->> RID CTRL <<————————— // logic [slaver.IDSIZE+4-1:0] arid; // // always@(posedge clock,negedge rst_n) // if(~rst_n) arid <= '0; // else begin // if(slaver.axi_arvalid && slaver.axi_arready ) // arid <= slaver.axi_arid; // else if(p_arvalid && p_arready)begin // if(length >= PSIZE) // arid <= arid + 1'b1; // else arid <= '0; // end else arid <= arid; // end // //—-<< RID CTRL >>————————— // assign master.axi_arid = arid;

endmodule